QTreeView实现搜索功能并且关键字标红

1、需求描述

实现组织树搜索,关键字红色显示;搜索规则,名称匹配显示,没有匹配不显示,子节点匹配,父节点即使没有匹配也显示;

2.实现方法

(1)top节点名称匹配关键则显示,否则隐藏

void TreeTaskList::SlotFilterChanged(QString strText)
{
    m_TreeDelegate->setProperty("FilterString", strText);//给代理设置搜索关键字
    QRegExp regExp(strText, Qt::CaseInsensitive);
    for (int i = 0; i < m_modelTree->rowCount(); i++)
    {
        QStandardItem* topitem = m_modelTree->item(i, 0);
        bool iret = RecluserFindItem(topitem, regExp);

        QString strName = topitem->data(Qt::UserRole).toMap().value("name").toString();
        if (strName.contains(regExp) || iret == false)
        {
            ui.treeView->setRowHidden(i, topitem->index().parent(), false);
        }
        else
        {
            ui.treeView->setRowHidden(i, topitem->index().parent(), true);
        }
    }
}

(2)递归查看子节点名称是否匹配

如果子节点包含关键字,父节点没有包含关键字也要显示

bool TreeTaskList::RecluserFindItem(QStandardItem* pFItem, QRegExp strText)
{

    bool rethidden = true;
    if (pFItem == NULL)
    {
        return rethidden;
    }

    int rowcount = pFItem->rowCount();
    for (int c = rowcount - 1; c >= 0; c--)
    {
        QStandardItem* childItem = pFItem->child(c, 0);
        if (childItem != NULL)
        {
            if (strText.isEmpty())
            {
                ui.treeView->setRowHidden(c, pFItem->index(), false);
                RecluserFindItem(childItem, strText);
                rethidden = false;
            }
            else
            {
                bool childret = RecluserFindItem(childItem, strText);
                if (childret == false)
                {
                    rethidden = false;
                }
                QString strName = childItem->data(Qt::UserRole).toMap().value("name").toString();
                if (strName.contains(strText) || childret == false)
                {
                    ui.treeView->setRowHidden(c, pFItem->index(), false);
                    rethidden = false;
                }
                else
                {
                    ui.treeView->setRowHidden(c, pFItem->index(), true);
                }
            }
        }

    }
    return rethidden;
}

3)匹配文字显示红色

要使搜索关键字变成红色,需要在代理中重写代理的paintevent函数,绘制文字颜色;根据设置给代理的属性"FilterString",就是搜索关键字,匹配名称,匹配的关键字设置为红色,文字长度超出范围,增加省略号;

void TreeTaskDelegate::paintName(QPainter *painter,QRect rect,QString strName) const
{
    QString filter = this->property("FilterString").isValid() ? this->property("FilterString").toString() : "";
    painter->save();

    QColor text_color = QColor(255, 255, 255, 0.7);          // 文本颜色
    QColor filter_color = QColor(250, 50, 57, 255);      // 高亮颜色
                                                         // 高亮文本
    QString filter_text = filter;  // 文字与过滤文字首先获取出来
    QString text = strName;
    QFont font;
    font.setPixelSize(16);
    font.setFamily("Microsoft YaHei UI");
    painter->setFont(font);
    QFontMetrics font_metrics(font);
    int realwidth=font_metrics.width(text);
    int text_width = rect.width();
    QTextDocument m_LabelName;
    m_LabelName.setDefaultFont(font);

    // 右部显示省略号
    QFontMetrics font_width(font);
    //text = font_width.elidedText(text, Qt::ElideRight, text_width);
    // 然后将匹配项加上font-color标签,若非空的话
    if (!filter_text.isEmpty())
    {
        int last_index = text.lastIndexOf(filter_text, -1, Qt::CaseInsensitive);
        while (last_index != -1)
        {
            text.insert(last_index + filter_text.length(), "</font>");
            text.insert(last_index, QString("<font color=%1>").arg(filter_color.name()));
            last_index = text.lastIndexOf(filter_text, last_index, Qt::CaseInsensitive);
        }
    }

    // 在文档中设置字体,并设置文字
    QString strColorText = QString("<font color=%1>%2</font>").arg(text_color.name()).arg(text);
    m_LabelName.setHtml(strColorText);
    int y =40;//居中显示高度
    y = (y - 24) / 2;
    if (y < 0)
    {
        y = 0;
    }
    QRect text_rect = rect;  // 文字高度为20,所以文字上下空白为6px
    int h1 = text_rect.height();
    int h2 = font_metrics.height();
    painter->translate(QPoint(text_rect.x(), text_rect.y() -2));// +(text_rect.height() - font_metrics.height()) / 2)
    m_LabelName.drawContents(painter, text_rect.translated(-text_rect.x(), -text_rect.y()));
    painter->restore();
    if (realwidth > text_rect.width())//超过长度绘制省略号
    {
        QRect rectsl = QRect(text_rect.right()+1, text_rect.y(), 20, 24);
        painter->drawText(rectsl, Qt::AlignLeft | Qt::AlignVCenter, "");
    }
}

 

posted @ 2024-09-14 17:28  一字千金  阅读(159)  评论(0编辑  收藏  举报