Qt之自定义检索框

时间:2022-08-09 10:31:03

1、效果展示

今天这篇文章主要讲解的是自定义搜索框,不仅仅支持搜索,而且可以支持搜索预览,具体请看效果图1。网上也有一些比较简单明了的自定义搜索框,比如Qt之自定义搜索框,讲的也比较详细,不过本文的侧重点不仅仅是搜索,而且包括了检索功能。有兴趣的小伙伴可以看下步骤3的思路讲解。

Qt之自定义检索框

图1 自定义搜索框

2、功能分析

这个自定义搜索框支持输入一定的数据源,然后通过检索窗口进行搜索数据,匹配到的数据会优先展示到预览下拉框,预览窗口支持hover高亮整行。仔细阅读demo源码的同学可能就会发现其实这个搜搜框的左侧又一个按钮是可以点击的,但是目前还没有添加具体的点击功能。了解了这个控件的功能之后,如果觉得对你有用,那么就可以接着继续往下看实现流程。

3、思路讲解

问题分析:

1、数据源存储在哪儿?怎么实现检索

2、弹出式下拉框显示和隐藏控制?位置同步?

3、鼠标hover状态的颜色设置?

首先在讲解源码之前,我抛出了3个问题,有精力的同学可以先思考下这几个问题,然后在接着往下看,下边我也会逐一说明这个些问题。

源码讲解:

1、使用到的类:

StockSortFilterProxyModel:过滤数据源,该model上的数据索引直接供视图展示
StockTableView:自定义视图,用于显示预览数据
StockListWidget:自定义搜索框
StockItemDelegate:自定义委托,提供自定义绘图

上边4个类是完成自定义搜索框的自定义类,当然除了上述4个类以外,还用到了qt自带的一些类,更好的理解这些类,那么这个自定义控件的思路也就显得异常好理解。

2、头文件说明

  • 委托:负责视图绘制
 class IView;

 struct StockItemDelegatePrivate
{
int column = ;//进度条所在列,下标从0开始
QTableView * parent = nullptr;
IView * view = nullptr;
}; class StockItemDelegate : public QStyledItemDelegate
{
Q_OBJECT public:
StockItemDelegate(QTableView * parent = nullptr);
~StockItemDelegate(){}; public:
void setView(IView * view); protected:
virtual void paint(QPainter * painter
, const QStyleOptionViewItem & option
, const QModelIndex & index) const Q_DECL_OVERRIDE; virtual QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const Q_DECL_OVERRIDE; private:
QScopedPointer<StockItemDelegatePrivate> d_ptr;
};
  • 窗口布局:StockTableView是专门用来展示检索后的数据,StockListWidget是窗口布局
 class IView
{
public:
virtual void SetMouseOver(int) = ;
}; class StockTableView : public QTableView, public IView
{
Q_OBJECT
public:
StockTableView(QStandardItemModel * model, QWidget * parent = ); public:
void SetMouseOver(int); protected:
virtual void mouseMoveEvent(QMouseEvent * event) override;
virtual void leaveEvent(QEvent * event) override;
virtual void mousePressEvent(QMouseEvent * event) override; private:
int currHovered;
void disableMouseOver(); private:
QStandardItemModel * m_pSourceModel;
}; struct StockListWidgetPrivate; class StockListWidget : public QWidget, public QAbstractNativeEventFilter
{
Q_OBJECT public:
StockListWidget(QWidget * parent = nullptr);
~StockListWidget(); public slots:
void NativeParentWindowMove(); protected:
virtual void moveEvent(QMoveEvent * event) override;
virtual bool nativeEventFilter(const QByteArray & eventType, void * message, long * result) override; private:
void InitializeUI(); private:
QScopedPointer<StockListWidgetPrivate> d_ptr;
};
  • 数据源:根据模式串匹配检索后的数据,并负责通知视图进行更新展示
 class StockSortFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT public:
StockSortFilterProxyModel(QObject *parent = nullptr);
~StockSortFilterProxyModel(); void SetFilterContext(const QString & pattern); protected:
bool lessThan(const QModelIndex &left
, const QModelIndex &right) const;
bool filterAcceptsRow(int source_row
, const QModelIndex & source_parent) const;
private:
size_t sortColumn = ;
};

3、窗口布局:

窗口布局:也就是这个检索框长什么样子,效果展示图1中就可以看到,在这个dmeo中,也就是StockListWidget类,该类使用了一个水平布局添加了按钮和文本输入框。当文本输入框内容发生变化时,启动检索,然后刷新视图上的数据,具体看源码

 connect(d_ptr->m_pSearchLineEdit, &QLineEdit::textChanged, this, [this](const QString & text){
if (d_ptr->m_pFilterModel)
{
d_ptr->m_pFilterModel->SetFilterContext(text);//根据检索内容刷新model
}
if (d_ptr->m_pStockPreviewWidget)
{
d_ptr->m_pStockPreviewWidget->move(d_ptr->m_pTitleWidget->mapToGlobal(QPoint(, d_ptr->m_pTitleWidget->height())));
int rowHeight = d_ptr->m_pStockPreview->rowHeight();
int rowCount = d_ptr->m_pFilterModel->rowCount();
d_ptr->m_pStockPreviewWidget->setFixedHeight(rowHeight * rowCount > DropWidgetMaxHeight ? DropWidgetMaxHeight : rowHeight * rowCount);
d_ptr->m_pStockPreviewWidget->show();//修正view高度,挪动位置并显示
}
});

4、数据存储

qt提供了一些列的model来供我们使用,有可以存放数据的,也有一些只供我们使用接口的,在这个demo中我使用的是QStandardItemModel,他可以存储我们所需要检索的源数据,然后qt还提供了一个检索model,QSortFilterProxyModel,我继承该model可以做自己想做的检索实现,然后把检索到的数据索引通知到视图,这样就完成了数据更新,具体关联代码如下:

     StockItemDelegate * itemDelegate = new StockItemDelegate(d_ptr->m_pStockPreview);
d_ptr->m_pStockPreview->setItemDelegate(itemDelegate);
itemDelegate->setView(d_ptr->m_pStockPreview);//委托关联到视图上,负责数据绘制 d_ptr->m_pStockPreviewWidget->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::Popup); d_ptr->m_pFilterModel->setSourceModel(d_ptr->m_pListModel);//检索model检索的数据源设置
d_ptr->m_pStockPreview->setModel(d_ptr->m_pFilterModel);//视图展示的model为检索后的model

数据检索实现,我匹配的是每一列是否为需要的值,也就是如果这一行中某一列满足要求都认为该行满足要求

 bool StockSortFilterProxyModel::filterAcceptsRow(int source_row
, const QModelIndex & source_parent) const
{
QRegExp regExp = filterRegExp();
bool result = false;
for (int i = ; i < sortColumn; ++i)//循环匹配所有的列,有一列满足要求就返回true
{
QModelIndex index = sourceModel()->index(source_row, i, source_parent);
QString context = sourceModel()->data(index).toString(); if (regExp.isEmpty() == false)
{
QString regExpStr = regExp.pattern();
result = regExp.exactMatch(context);
} if (result)
{
break;
}
} return result;
}

5、视图显示

关于视图显示,主要是视图显示位置和显示时机

显示时机:编辑框内容发现变化的时候显示,编辑框失去焦点的时候隐藏,这样也就存在一个问题,当主窗口拖动时,视图位置更新怎么做?

显示位置:当主窗口位置移动时,更新视图位置,这个方法看一参考qt捕获全局windows消息

6、视图背景色

视图背景色在添加数据源的时候设置了默认背景色,在后hover的时候重新设置背景色,hover失效后再恢复默认背景色,实现行hover代码如下:

 void StockTableView::SetMouseOver(int row)
{
if (row == currHovered)
{
return;
} StockSortFilterProxyModel * sortModel = static_cast<StockSortFilterProxyModel *>(model());
if (sortModel->rowCount() <= row)
{
return;
}
for (int col = ; col < sortModel->columnCount(); col++)//循环遍历,设置指定行中每一个item的背景色
{
QModelIndex index = sortModel->index(row, col);
if (index.isValid())
{
if (QStandardItem * item = m_pSourceModel->itemFromIndex(sortModel->mapToSource(index)))
{
item->setBackground(QBrush(QColor(, , )));
}
}
} if (currHovered != -)
{
disableMouseOver();//恢复之前hover的行
}
currHovered = row;
}

4、相关文章

5、demo下载链接:

Qt之自定义检索框

如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!! 

 
Qt之自定义检索框 Qt之自定义检索框

很重要--转载声明

  1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords
  2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。

Qt之自定义检索框的更多相关文章

  1. Qt之自定义搜索框

    简述 关于搜索框,大家都经常接触.例如:浏览器搜索.Windows资源管理器搜索等. 当然,这些对于Qt实现来说毫无压力,只要思路清晰,分分钟搞定. 方案一:调用QLineEdit现有接口 void ...

  2. 【Qt】Qt之自定义搜索框【转】

    简述 关于搜索框,大家都经常接触.例如:浏览器搜索.Windows资源管理器搜索等. 当然,这些对于Qt实现来说毫无压力,只要思路清晰,分分钟搞定. 简述 效果 细节分析 Coding 源码下载 效果 ...

  3. Qt之自定义搜索框——QLineEdit里增加一个Layout,还不影响正常输入文字(好像是一种比较通吃的方法)

    简述 关于搜索框,大家都经常接触.例如:浏览器搜索.Windows资源管理器搜索等. 当然,这些对于Qt实现来说毫无压力,只要思路清晰,分分钟搞定. 方案一:调用QLineEdit现有接口 void ...

  4. Qt 之 自定义提示信息框—迅雷风格(模拟QDialog类的exec&lpar;&rpar;方法) good

    http://blog.csdn.net/goforwardtostep/article/details/53614830

  5. Qt之自定义QLineEdit右键菜单

    一.QLineEdit说明 QLineEdit是单行文本框,不同于QTextEdit,他只能显示一行文本,通常可以用作用户名.密码和搜索框等.它还提供了一些列的信号和槽,方便我们使用,有兴趣的小伙伴可 ...

  6. Qt之等待提示框(QPropertyAnimation)

    简述 之前分享过QLabel可以通过QMovie播放gif图片,可以实现等待提示框,今天主要使用动画QPropertyAnimation来进行实现! 数据加载的时候,往往都需要后台线程进行数据请求,而 ...

  7. Qt之自定义托盘&lpar;二&rpar;

    上一篇文章讲述了自定义Qt托盘,不过不是使用QSystemTrayIcon这个类,而是我们自己完全自定义的一个类,我们只需要处理这个类的鼠标hover.鼠标左键点击.鼠标右键点击和鼠标左键双击,就可以 ...

  8. 在ASP&period;NET中引用自定义提示框

    在html网页中自定义提示框 正文: 在一般的B/S架构中项目,与用户的交互信息是非常重要的.在一般的情况下,设计人员都在把用户信息呈现在html中,用div和span去弹出相关信息.对于一般的情况而 ...

  9. Qt之等待提示框(QMovie)

    简述 关于gif的使用在实际项目中我用的并不多,因为我感觉瑕疵挺多的,很多时候锯齿比较严重,当然与图存在很大的关系. 关于生成gif的方法可以提供一个网站preloaders,基本是可以满足需求的. ...

随机推荐

  1. jQuery技巧

    回到顶部按钮 图片预加载 判断图片是否加载完 自动修补破损图像 Hover切换class类 禁用输入 停止正在加载的链接 toggle fade/slide 简单的手风琴 使两个DIV同等高度 在浏览 ...

  2. PHP&plus;ajaxfileupload与jcrop插件结合 完成头像上传

    昨天花了点时间整合了一下头像插件 东拼西凑的成果 先来看下效果

  3. 没有为 COM 互操作注册程序集 请使用 regasm&period;exe &sol;tlb 注册该程序集——解决办法

    错误现象: 错误 6 没有为 COM 互操作注册程序集“DevExpress.Utils.v13.1, Version=13.1.7.0, Culture=neutral, PublicKeyToke ...

  4. Servlet访问第一次500,刷新后404的解决办法

    第一次运行错误:HTTP Status 500 -  --------------------------------------------type Exception reportmessage  ...

  5. IOS系统概述与层次

    一.概述 IOS是apple公司为其自己的移动设备(iPhone,iPod touch,iPad)而开发的操作系统,IOS许多的技术是基于苹果的Mac OSX桌面系统的,如果你开发过苹果的mac系统应 ...

  6. fetchField 和 fetchColumn

    public function fetchField($index = 0) { // Call PDOStatement::fetchColumn to fetch the field. retur ...

  7. HTML5 Canvas图片操作简单实例1

    1.加载显示图片 <canvas id="canvasOne" class="myCanvas" width="500" height ...

  8. 利用raspberry pi搭建typecho笔记&lpar;二&rpar; sqlite和typecho部署

    sqlite概述 typecho可以支持MYSQL和Sqlite两种数据库,因为Sqlite更为轻量,并且不需要额外的进程,而是直接对数据库文件进行读取,所以配置相对于MySQL也更为简单,仅需指定数 ...

  9. Ant部署(linux)

    1.下载 mkdir /opt/ant cd /opt/ant wget http://mirror.bit.edu.cn/apache//ant/binaries/apache-ant-1.9.4- ...

  10. linux dhcp搭建及pxe无人值守装机

    DHCP动态主机配置协议:由IETF组织制定,用来简化主机ip地址分配管理可以自动分配的入网参数ip地址/子网掩码/广播地址默认网关地址DNS服务器地址 ----------------------- ...