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

点击下载完整代码

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

相关推荐
淼淼76315 分钟前
Qt调度 程序
开发语言·c++·windows·qt
明飞198732 分钟前
QT笔记1
qt
林政硕(Cohen0415)35 分钟前
ARM Qt 字体过小的问题
arm开发·qt
追烽少年x1 小时前
Qt中构建多语言程序
qt
rainFFrain3 小时前
QT显示类控件---QSlider
开发语言·qt
扶尔魔ocy7 小时前
【QT window】multimedia+ffmpeg实现(PCM和MP4)录音功能
qt·ffmpeg·pcm
YouEmbedded8 小时前
解码 Qt 交互:滑动交互、窗口拖拽
qt·滑动交互·上滑关闭·滑动显示 / 隐藏
郝学胜-神的一滴8 小时前
使用EBO绘制图形:解锁高效渲染与内存节省之道
c++·qt·游戏·设计模式·系统架构·图形渲染
枫叶丹49 小时前
【Qt开发】Qt事件(一)
c语言·开发语言·数据库·c++·qt·microsoft
刺客xs20 小时前
Qt------信号槽,属性,对象树
开发语言·qt·命令模式