Qt实战:自定义搜索跳转控件 | 附完整源码

1、目的

实现通过搜索,将搜索显示出来并可以点击进行跳转

2、效果
3、方法

使用QTreeWidget、QLineEdit进行实现

4、源码
a、头文件
cpp 复制代码
#ifndef SEARCHJUMPTREEWIDGET_H
#define SEARCHJUMPTREEWIDGET_H

#include <QDebug>
#include <QLineEdit>
#include <QStyledItemDelegate>
#include <QTreeWidget>
#include <QWidget>

struct SearchData {
  QString contextText;  // 项的内容
  QList<int> jumpPath;  // jump位置,tree的位置
};
Q_DECLARE_METATYPE(SearchData)

class SearchDelegate;
class SearchJumpTreeWidget : public QWidget {
  Q_OBJECT
 public:
  explicit SearchJumpTreeWidget(QWidget *parent = 0);

  void setTreeContext(const QList<SearchData> &dataList);

 signals:
  void signalSearch(const QString &text);
  void signalSelect(const SearchData &itemData);

 private slots:
  void slotSearchEditReturnPressed();
  void slotTreeDoubleClicked(QTreeWidgetItem *item, int column);

 private:
  QLineEdit *searchEdit = nullptr;
  QTreeWidget *treeWidget = nullptr;
  SearchDelegate *searchDelegate = nullptr;
};

// 自定义代理,将搜索文字改变颜色
class SearchDelegate : public QStyledItemDelegate {
  Q_OBJECT

 public:
  SearchDelegate(QObject *parent = nullptr);

  void setSearchText(const QString &text);

  void paint(QPainter *painter, const QStyleOptionViewItem &option,
             const QModelIndex &index) const override;

 private:
  QString searchText;
  QRegularExpression regExp;
};
#endif  // SEARCHJUMPTREEWIDGET_H
b、源文件
cpp 复制代码
#pragma execution_character_set("utf-8")
#include "searchjumptreewidget.h"

#include <QHeaderView>
#include <QPainter>
#include <QTextDocument>
#include <QVBoxLayout>

SearchJumpTreeWidget::SearchJumpTreeWidget(QWidget *parent) : QWidget(parent) {
  QVBoxLayout *mainLay = new QVBoxLayout(this);

  searchEdit = new QLineEdit(this);
  searchEdit->setPlaceholderText("请输入搜索内容");
  mainLay->addWidget(searchEdit);
  treeWidget = new QTreeWidget(this);
  mainLay->addWidget(treeWidget);
  treeWidget->setHeaderLabel("内容");
  treeWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
  treeWidget->setEditTriggers(QTreeView::NoEditTriggers);
  treeWidget->header()->setVisible(false);
  searchDelegate = new SearchDelegate(this);
  treeWidget->setItemDelegate(searchDelegate);
  connect(treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
          SLOT(slotTreeDoubleClicked(QTreeWidgetItem *, int)));

  connect(searchEdit, SIGNAL(returnPressed()),
          SLOT(slotSearchEditReturnPressed()));
}

void SearchJumpTreeWidget::setTreeContext(const QList<SearchData> &dataList) {
  treeWidget->clear();
  treeWidget->header()->setVisible(false);
  for (const SearchData &data : dataList) {
    QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
    item->setText(0, data.contextText);
    QVariant var = QVariant::fromValue(data);
    item->setData(0, Qt::UserRole + 1, var);
    treeWidget->addTopLevelItem(item);
  }
  if (dataList.size() > 0) {
    searchDelegate->setSearchText(searchEdit->text());
    treeWidget->header()->setVisible(true);
  }
}

void SearchJumpTreeWidget::slotSearchEditReturnPressed() {
  QString searchStr = searchEdit->text();
  if (searchStr.isEmpty()) {
    treeWidget->clear();
    treeWidget->header()->setVisible(false);
  } else {
    emit signalSearch(searchStr);
  }
}

void SearchJumpTreeWidget::slotTreeDoubleClicked(QTreeWidgetItem *item,
                                                 int column) {
  if (!item) return;
  QVariant var = item->data(0, Qt::UserRole + 1);
  if (var.canConvert<SearchData>()) {
    SearchData itemData = var.value<SearchData>();
    emit signalSelect(itemData);
  }
}

SearchDelegate::SearchDelegate(QObject *parent) : QStyledItemDelegate(parent) {}

void SearchDelegate::paint(QPainter *painter,
                           const QStyleOptionViewItem &option,
                           const QModelIndex &index) const {
  QStyleOptionViewItem opt = option;
  initStyleOption(&opt, index);

  // 绘制选中背景颜色
  painter->save();
  QString defaultStr("<span style='color: black;'>%1</span>");
  if (opt.state & QStyle::State_Selected) {
    painter->fillRect(opt.rect, QBrush(QColor(15, 130, 220)));
  }
  painter->restore();

  // 整理文字
  QString text = index.data(Qt::DisplayRole).toString();
  const int len = searchText.length();
  QString html("<style>body { white-space: pre; }</style>");
  int pos = 0;
  while ((pos = text.indexOf(regExp, pos)) != -1) {
    QString preText = text.left(pos);
    QString curText = text.mid(pos, len);
    if (!preText.isEmpty()) {
      html += defaultStr.arg(preText);
    }
    if (!curText.isEmpty()) {
      html += QString("<span style='color: red;'>%1</span>").arg(curText);
    }
    text = text.mid(pos + len);
    pos = 0;
  }
  if (!text.isEmpty()) {
    html += defaultStr.arg(text);
  }
  QTextDocument doc;
  doc.setHtml(html);
  //    doc.setTextWidth(opt.rect.width());

  // 绘制文字
  painter->save();
  painter->translate(opt.rect.left(), opt.rect.top());
  QRect clip(0, 0, opt.rect.width(), opt.rect.height());
  doc.drawContents(painter, clip);
  painter->restore();
}

void SearchDelegate::setSearchText(const QString &text) {
  searchText = text;
  regExp =
      QRegularExpression(searchText, QRegularExpression::CaseInsensitiveOption);
}

点击下载完整代码

对你有用就点个赞👍,以后需要用到就收藏⭐

相关推荐
AGANCUDA2 小时前
qt使用osg显示pcd点云的例子
开发语言·qt
寻找华年的锦瑟3 小时前
Qt-侧边栏布局
开发语言·qt
tyler-泰勒3 小时前
QT:基础概念操作
开发语言·qt
开始了码3 小时前
QT::对话框:消息对话框6
qt
xxp43213 小时前
Qt 网络编程 网络下载
网络·qt·php
YY&DS4 小时前
Qt 快速搭建局域网 HTTP 下载服务(兼容 IE/Chrome/Edge/Firefox)
chrome·qt·http
q***69774 小时前
使用 Qt 插件和 SQLCipher 实现 SQLite 数据库加密与解密
数据库·qt·sqlite
极地星光5 小时前
Qt/C++ 单例模式深度解析:饿汉式与懒汉式实战指南
c++·qt·单例模式
_OP_CHEN8 小时前
从零开始的Qt开发指南:(七)Qt常用控件之按钮类控件深度解析:从 QPushButton 到单选 / 复选的实战指南
qt·前端开发·qradiobutton·qpushbutton·qcheckbox·qt常用控件·gui界面开发
友友马21 小时前
『QT』窗口 (一)
开发语言·数据库·qt