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);
}

点击下载完整代码

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

相关推荐
努力还债的学术吗喽3 小时前
【项目】pyqt5基于python的照片整蛊项目
开发语言·python·qt
weixin_459548903 小时前
Qt对话框设计
qt
QT 小鲜肉12 小时前
【QT/C++】Qt定时器QTimer类的实现方法详解(超详细)
开发语言·数据库·c++·笔记·qt·学习
MeowKnight95812 小时前
【Qt】Qt实践记录3——UDP通信
笔记·qt
扶尔魔ocy17 小时前
【QT自定义2D控件】QGraphics绘制仪表盘
数据库·qt·microsoft
开心-开心急了18 小时前
关于Flutter与Qt for python 的一些技术、开源、商用等问题
开发语言·python·qt·flutter
友友马18 小时前
『 QT 』按钮类控件属性解析
开发语言·数据库·qt
QT 小鲜肉19 小时前
【Git、GitHub、Gitee】按功能分类汇总Git常用命令详解(超详细)
c语言·网络·c++·git·qt·gitee·github
老歌老听老掉牙1 天前
解决 PyQt5 中 sipPyTypeDict() 弃用警告的完整指南
python·qt