QPlainTextEdit遍历显示数据,高亮显示匹配行的方法

这篇博客介绍了如何在Qt应用程序中使用QPlainTextEdit控件展示软件操作日志,并实现搜索关键字及高亮显示功能。通过QTextDocument和QTextEdit的API,实现了搜索按钮点击后的文本遍历和高亮,同时提供了上一个和下一个搜索结果的导航。代码示例详细展示了关键步骤,包括清除之前的高亮和更新当前光标位置。
摘要由CSDN通过智能技术生成
	最近由于项目要求,需要显示软件操作日志且需要有搜索关键字功能。用到的控件是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新增数据后,上面的数据未更新的问题,自己改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值