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

点击下载完整代码

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

相关推荐
张人玉10 小时前
基于 Python 机器学习 与 PyQt5 桌面框架开发的可视化分析系统——基于大数据的网上购物消费行为分析可视化大屏
python·qt·机器学习·echarts·three.js
「QT(C++)开发工程师」11 小时前
C++11 std::unique_ptr — 独占所有权的智能指针
c语言·开发语言·c++·qt
小镇敲码人13 小时前
【深入浅出】之Qt 事件系统实战:鼠标、键盘、滚轮、窗口与定时器事件
数据库·qt·网络协议·mysql·http
小小龙学IT15 小时前
Qt 数据库编程(Qt SQL 模块)深度解析
数据库·sql·qt
Qt历险记17 小时前
C++11 std::unique_ptr — 独占所有权的智能指针
qt
宏笋18 小时前
一款集结古今中外文学查阅与编辑的软件
qt
机器视觉知识推荐、就业指导1 天前
为什么老说“纯 Qt 没啥就业市场”?
开发语言·qt
telepan1 天前
Qt 开发避坑与性能指南:如何优雅、安全地定义全局常量字符串?
开发语言·qt
小灰灰搞电子1 天前
完全驾驭 Qt 与数据库:C++ ORM 框架 QxOrm 原理与实践指南
数据库·c++·qt
QT界面美化性能优化1 天前
QT+AI:使用AI技术为QT应用程序赋能
c++·人工智能·qt·opencv·qt教程·qt6.3