最近由于项目要求,需要显示软件操作日志且需要有搜索关键字功能。用到的控件是QPlainTextEdit,之所以不用QTextEdit显示文本,是因为当日志数据一多会造成程序卡顿(实测过,特别是用在嵌入式设备里面)。话不多说,直接上代码。
以下是关键代码:
.h文件
private:
QTextDocument *loginDoc; //plainTextEdit加载的文本对象
int loginDocNum; //文档中的文本块的数量,回车符是一个block
int loginCurrentDocNum; //当前遍历到loginDocNum的第几个数据
.cpp文件
//点击搜索按钮查找相应字段、并高亮显示查到的第一个数据所在行
void searchText()
{
QString text = ui->lineEdit->text().trimmed();
if(nullptr == text)
{
myHelper::ShowMessageBoxError(QString("搜索内容不能为空!"));
return;
}
loginDoc = ui->txtMain->document(); //返回plainTextEdit加载的文本对象
loginDocNum = loginDoc->blockCount() ;//返回文档中的文本块的数量,回车符是一个block
travPlainTextDoc(index,loginDocNum,loginDoc,text);//index是我所使用到的控件stacketWidget的currentIndex,不用管。这个函数里面就是遍历数据以及高亮显示。
}
//遍历并高亮显示查询到的第一个数据所在行
void travPlainTextDoc(int index,int docNum,QTextDocument *doc,QString text)
{
//2021-7-23 若之前设置了标记,需要将之前的标记颜色改为背景色
recoverExtraSelection(index);
for (int i = 0; i < docNum; i++)
{
QTextBlock textLine = doc->findBlockByNumber(i) ; // 文本中的一段
QString str = textLine.text();
if(str.contains(text))
{
QList<QTextEdit::ExtraSelection> extraSelections;//提供一种方式显示选择的文本
if(index == 0)
{
loginCurrentDocNum = i;
extraSelections = ui->txtMain->extraSelections();//获取之前高亮的设置
ui->txtMain->setTextCursor(QTextCursor(textLine));//更新可见光标
}
QTextEdit::ExtraSelection selection;
QColor lineColor = QColor("#F79332");
selection.format.setBackground(lineColor);
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
if(index == 0)
{
selection.cursor = ui->txtMain->textCursor();
}
selection.cursor.clearSelection();//通过设置锚到光标位置清除当前的选择
extraSelections.append(selection);
if(index == 0)
{
ui->txtMain->setExtraSelections(extraSelections);//设置高亮
}
//查找到第一个就返回
return;
}
}
}
//清除上一次的高亮行设置
void recoverExtraSelection(int index)
{
QList<QTextEdit::ExtraSelection> selections;
if(index == 0)
{
selections = ui->txtMain->extraSelections();
}
//这一步是高亮之前的颜色,没有这一步即使选择下一行高亮了,上一行高亮的也不会消失。不想恢复的当我没说。
for(int i = 0;i < selections.count();i++)
{
QColor lineColor = QColor("#646464");
selections.at(i).format.setBackground(lineColor);
selections.at(i).format.setProperty(QTextFormat::FullWidthSelection, true);
}
if(selections.count() > 0)
{
if(index == 0)
{
ui->txtMain->setExtraSelections(selections);//恢复背景色
ui->txtMain->extraSelections().clear();
}
}
}
//上一个,我没有写成循环的遍历的
void on_btn_searchLast_clicked()
{
int index = ui->stackedWidget->currentIndex();
QString text = ui->lineEdit->text().trimmed();
if(nullptr == text)
{
myHelper::ShowMessageBoxError(QString("当前搜索内容为空!"));
return;
}
int currentDocNum = 0;
int docNum = 0;
QTextDocument *doc = nullptr;
if(index == 0)
{
currentDocNum = loginCurrentDocNum;
docNum = loginDocNum;
doc = loginDoc;
}
if(currentDocNum == 0)
{
return;
}
recoverExtraSelection(index);
for(int i = currentDocNum - 1;i < docNum;i--)
{
QTextBlock textLine = doc->findBlockByNumber(i) ; // 文本中的一段
QString str = textLine.text();
if(str.contains(text))
{
QList<QTextEdit::ExtraSelection> extraSelections;//提供一种方式显示选择的文本
if(index == 0)
{
loginCurrentDocNum = i;
extraSelections = ui->txtMain->extraSelections();//获取之前高亮的设置
ui->txtMain->setTextCursor(QTextCursor(textLine));//更新可见光标
}
QTextEdit::ExtraSelection selection;
QColor lineColor = QColor("#F79332");
selection.format.setBackground(lineColor);
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
if(index == 0)
{
selection.cursor = ui->txtMain->textCursor();
}
selection.cursor.clearSelection();//通过设置锚到光标位置清除当前的选择
extraSelections.append(selection);
if(index == 0)
{
ui->txtMain->setExtraSelections(extraSelections);//设置高亮
}
return;
}
}
}
//下一个
void on_btn_searchNext_clicked()
{
int index = ui->stackedWidget->currentIndex();
QString text = ui->lineEdit->text().trimmed();
if(nullptr == text)
{
myHelper::ShowMessageBoxError(QString("当前搜索内容为空!"));
return;
}
int currentDocNum = 0;
int docNum = 0;
QTextDocument *doc = nullptr;
if(index == 0)
{
currentDocNum = loginCurrentDocNum;
docNum = loginDocNum;
doc = loginDoc;
}
if(currentDocNum >= docNum - 1)
{
myHelper::ShowMessageBoxError(QString(""));
return;
}
recoverExtraSelection(index);
for(int i = currentDocNum + 1;i < docNum;i++)
{
QTextBlock textLine = doc->findBlockByNumber(i) ; // 文本中的一段
QString str = textLine.text();
if(str.contains(text))
{
QList<QTextEdit::ExtraSelection> extraSelections;//提供一种方式显示选择的文本
if(index == 0)
{
loginCurrentDocNum = i;
extraSelections = ui->txtMain->extraSelections();//获取之前高亮的设置
ui->txtMain->setTextCursor(QTextCursor(textLine));//更新可见光标
}
QTextEdit::ExtraSelection selection;
QColor lineColor = QColor("#F79332");
selection.format.setBackground(lineColor);
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
if(index == 0)
{
selection.cursor = ui->txtMain->textCursor();
}
selection.cursor.clearSelection();//通过设置锚到光标位置清除当前的选择
extraSelections.append(selection);
if(index == 0)
{
ui->txtMain->setExtraSelections(extraSelections);//设置高亮
}
return;
}
}
}
上一个和下一个的代码未考虑到:当plainTextEdit新增数据后,上面的数据未更新的问题,自己改。