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,所以文字上下空白为6pxint 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, "…");} }