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, "…"); } }
标签:index,QTreeView,text,filter,关键字,标红,font,rect,QString From: https://www.cnblogs.com/bclshuai/p/18414403