说起下拉框,想必大家都比较熟悉,在我们注册一些网站的时候,会出现大量的地区数据供我们选择,这个时候出现的就是下拉框列表,再比如字体选择的时候也是使用的下拉框,如图1所示。下拉框到处可见,作为一个图形库,qt也提供了QtComboBox类来供我们使用,但是有些时候简单的下拉列表已经满足不了我们的需求,如图2所示,是一个下拉表格,这个时候就需要我们自己定制一下QComboBox。

图1

图2

上边说了我们需求的变化,接下来我就讲述一下关于QComboBox定制的一些内容,本片文章我就只讲述两种常用的下拉选项控制,分别是列表和表格

一、列表的实现

首先我上一张qq的登录框,如图3所示,下拉列表里不仅仅是一个文字描述或者复选框,而是含有图片文字和关闭按钮的复杂窗口,那么这个时候简单的QComboBox是完成不了这项功能的,要做到像qq这样美观的功能是需要我们自己做一定的处理

图3

列表窗口定制步骤如下:

1、首先我们需要自定义一个窗口,上边有我们需要操作的内容,这个窗口讲会是QComboBox下拉框中的一项,我自己定义的类名为CActionContentWidget,头文件如下:

1 class CActionContentWidget : publicQWidget2 {3 Q_OBJECT4 signals:5 voidIconClicked();6 void showText(const QString &);7

8 public:9 CActionContentWidget(const QString & text, QWidget * parent =nullptr);10 ~CActionContentWidget();11

12 public:13 void SetContentText(const QString & text);//设置显示文字

14 void SetItemIcon(const QString & icon, const QString & hover);//设置图标

15

16 public:17 void SetBackgroundRole(boolhover);18

19 protected:20 virtual void enterEvent(QEvent *) Q_DECL_OVERRIDE;//暂时没用

21 virtual void leaveEvent(QEvent *) Q_DECL_OVERRIDE;//暂时没用

22 virtual bool eventFilter(QObject *, QEvent *) Q_DECL_OVERRIDE;23 virtual void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE;24

25

26 virtual void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE;27

28 private:29 voidInitializeUI();30

31 private:32 bool m_Mouse_press = false;33 QWidget * m_ContentWidget =nullptr;34 QPushButton * m_ActIcon =nullptr;35 QLabel * m_ActText =nullptr;36 };

这个窗口支持鼠标hover事件,并且我自己实现了鼠标按下和弹起方法,为的是自己控制QComboBox下拉框的隐藏,接口SetBackgroundRole是控制窗口背景色变化的函数,由于enterEvent和leaveEvent方法在成为了代理窗口后,事件触发我自己也没有搞清楚是怎么回事,因此我使用了installEventFilter方法把该窗口的事件放到父窗口去处理,在窗口中判断鼠标当前位置和CActionContentWidget 窗口之间的关系来判断鼠标是否进入该窗口。

图4

2、如图4所示,是我实现的结果预览,接下来我们需要把定制的窗口放到QComboBox的下拉框中,代码如下:

1 class combobox : publicQWidget2 {3 Q_OBJECT4

5 public:6 combobox(QWidget *parent = 0);7 ~combobox();8

9 protected:10 virtual bool eventFilter(QObject *, QEvent *) Q_DECL_OVERRIDE;11

12 private:13 void ConstructList();//列表定制

14 void ConstructTable();//表格定制

15

16 private:17 Ui::comboboxClass ui;18 };

ConstructList方法是列表的定制,也就是上图4所示的效果,ConstructTable方法内封装的是定制表格,后续我会讲解。

3、上边提到定制的窗口和鼠标位置的判断是在父窗口中进行的,那么接下来我就解释下父窗口的eventFIlter方法。代码比较简单,我就不一一进行解释了

1 bool combobox::eventFilter(QObject * watched, QEvent * event)2 {3 if (watched->inherits("QWidget") && event->type() ==QEvent::Paint)4 {5 if (CActionContentWidget * actionItem = dynamic_cast(watched))6 {7 if (actionItem->rect().contains(actionItem->mapFromGlobal(QCursor::pos())))8 {9 actionItem->SetBackgroundRole(true);10 }11 else

12 {13 actionItem->SetBackgroundRole(false);14 }15 }16 }17

18 return QWidget::eventFilter(watched, event);19 }

4、ConstructList列表实现,代码如下:

1 voidcombobox::ConstructList()2 {3 QListWidget * listWidget = newQListWidget;4 listWidget->setViewMode(QListView::ListMode);5

6 for (int i = 0; i < 5; i++)7 {8 CActionContentWidget * itemWidget = new CActionContentWidget("fawefawe");9 connect(itemWidget, &CActionContentWidget::showText, this, [this, listWidget](const QString &text){10 ui.comboBox->hidePopup();11 if (ui.comboBox->isEditable())12 {13 ui.comboBox->setCurrentText(text);14 }15 else

16 {17 for (int c = 0; c < listWidget->count(); ++c)18 {19 CActionContentWidget * itemWidget = dynamic_cast(listWidget->itemWidget(listWidget->item(c)));20 if (itemWidget ==sender())21 {22 ui.comboBox->setCurrentIndex(c);23 }24 }25 }26 });27 itemWidget->SetItemIcon(":/combobox/Resources/icon1.jpg", ":/combobox/Resources/icon1.jpg");28 itemWidget->setFixedHeight(45);29 itemWidget->setFixedWidth(150);30 QListWidgetItem * item = newQListWidgetItem(listWidget);31 item->setText(QStringLiteral("%1").arg(i));32 //item->setCheckState(Qt::Checked);

33 listWidget->setItemWidget(item, itemWidget);34 listWidget->addItem(item);35 itemWidget->installEventFilter(this);36 }37

38 ui.comboBox->setModel(listWidget->model());39 ui.comboBox->setView(listWidget);40 ui.comboBox->setEditable(true);//是否支持下拉框可编辑

41 ui.comboBox->setMaxVisibleItems(3);42

43 setStyleSheet("QComboBox{border:1px solid gray;}"

44 "QComboBox QAbstractItemView::item{height:45px;}" //下拉选项高度

45 "QComboBox::down-arrow{image:url(:/combobox/Resources/icon1.jpg);}" //下拉箭头

46 "QComboBox::drop-down{border:0px;}"); //下拉按钮

47 }

View Code

其中的setStyleSheet是用来设置下拉框中每一项的信息的,我们自己定制的窗口只是覆盖在原有窗口之上而已,原有的窗口还是存在的,因此我们的窗口必须和定制的窗口大小一样,负责会出现一些意外的情况。初次之外还需要注意的是:设置下拉框是否可编辑,如图5帮助文档所描述,QComboBox在可编辑状态下可以通过setCurrentText来设置displayText,但是如果不可编辑,他则会显示当前原有窗口的text,而非我们自己定制的窗口内容,因此我在showText信号的处理槽中,判断了下下拉框是否可编辑,并做相应的处理。

图5

还有几个设置下拉框属性的接口,我就不一一细说了,想了解的同学自己看帮助文档吧。其中setModel和setView是两居重点的代码,千万不能忘记,这两句代码是把QComboBox的视图和数据跟QListWidget绑定在一起了。QListWidget还支持ViewMode::IconMode这种现实模式,但是我们的下拉框定制用不到,因此我就不讲解这个了。

5、到此我们的列表定制就完成了。

二、表格实现

看明白了列表的实现,表格的实现就不在话下,不过我们列表的实现和表格的实现我在实现的时候还是有一定的区别的,有兴趣的同学可以接着往下看。首先就说下拉框的隐藏这一事件就和列表不一样,表格我是使用QTableWidget,内容使用QCheckBox,我自己重写了QCheckBox,并重新是了hitButton这个方法,因为当这个方法返回false时,鼠标点击不会选中/取消选中选择框,这个时候事件循环应该是传递到了父窗口上,而窗口把弹框隐藏了,这样做显然不满足我们的需求,有时候我们可能需要进行多个选择。说完需求之后我们来看代码。

1、首先我自己重写了QCheckBox,头文件代码如下:

1 class CheckBox : publicQCheckBox2 {3 public:4 CheckBox(QWidget * parent =nullptr) :QCheckBox(parent){}5 ~CheckBox(){};;6

7 protected:8 virtual voidcheckStateSet() Q_DECL_OVERRIDE;9 virtual bool hitButton(const QPoint & pos) constQ_DECL_OVERRIDE;10 virtual voidnextCheckState() Q_DECL_OVERRIDE;11 };

大多数函数都是没有做处理,仅仅对hitButton方法做了重写,返回值直接返回true。这个时候就我们就可以进行多项选择,而弹框也不会消失。最终的实现效果如图6所示

图6

2、ConstructTable方法的实现如下:

1 voidcombobox::ConstructTable()2 {3 setStyleSheet("QComboBox QAbstractItemView {selection-background-color: transparent;}");4

5 QTableWidget * tableWidget = new QTableWidget(3, 3);6 tableWidget->verticalHeader()->setVisible(false);7 tableWidget->horizontalHeader()->setVisible(false);8 tableWidget->setShowGrid(false);9 for (int i = 0; i < 3; ++i)10 {11 tableWidget->setColumnWidth(i, 49);12 tableWidget->setRowHeight(i, 50);13 for (int j = 0; j < 3; ++j)14 {15 /*CActionContentWidget *itemWidget = new CActionContentWidget("fawefawe");16 itemWidget->SetItemIcon(":/combobox/Resources/icon1.jpg", ":/combobox/Resources/icon1.jpg");17 itemWidget->setFixedHeight(50);18 itemWidget->setFixedWidth(50);*/

19 CheckBox * itemWidget = newCheckBox;20 itemWidget->setFixedSize(50, 50);21 itemWidget->setStyleSheet(QString("QCheckBox {background-color:lightgray;}"

22 "QCheckBox:checked{background-color:white;}"));23 connect(itemWidget, &QCheckBox::clicked, this, [this]{24 QObject * sender = this->sender();25 if (QCheckBox * item = dynamic_cast(sender))26 {27 QString text = ui.comboBox->currentText();28 if (text.isEmpty() == false)29 {30 if (item->isChecked())31 {32 if (text.split("|").indexOf(item->text()) == -1)33 {34 text.append("|" + item->text());35 }36 }37 else

38 {39 text.remove("|" + item->text());40 text.remove(item->text());41 if (text.size() != 0 && text.at(0) == '|')42 {43 text.remove(0, 1);44 }45 }46 }47 else

48 {49 if (item->isChecked())50 {51 text.append(item->text());52 }53 }54 ui.comboBox->setCurrentText(text);55 }56 });57 itemWidget->setText(QStringLiteral("好%1").arg(i));58 itemWidget->setCheckable(true);59 //tableWidget->setItem(i, j, new QTableWidgetItem(QStringLiteral("热分%1").arg(i)));

60 tableWidget->setCellWidget(i, j, itemWidget);61

62 itemWidget->installEventFilter(this);63 }64 }65

66 ui.comboBox->setModel(tableWidget->model());67 ui.comboBox->setView(tableWidget);68 //ui.comboBox->setEditable(true);

69 }

View Code

上边的代码都比较简单,我就不多了,我只说一个点,在设置表格列宽度的时候设置的为49,因为表格具有boder,如果设置50就会超出tableWidget,而出现左右滚动的现象

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

很重要--转载声明

本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords

如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。

qcombobox 隐藏_Qt之QComboBox定制相关推荐

  1. qt stylesheet 隐藏_Qt QDockWidget实现鼠标移出自动隐藏

    //不解释,自己看.不保证完整,仅供思路参考#include #include "TableView.h"#include #include int main(int argc, ...

  2. QComboBox的下拉多选

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.QComboBox的下拉多选 二.实现原理 1.下拉框点击不隐藏 2.选中下拉项内容显示 总结 前言 Qt的QCo ...

  3. QComboBox样式

    前言 我对qss只会一些简单的,所以每次都得查资料,自己调,好麻烦,特别是之前一篇博客关于菜单样式的设置.这次以为两者相似,结果不是的. 这个QComboBox下拉框的样式设置有稍微复杂,有些关键点得 ...

  4. QComboBox实现下拉框check勾选

    目录 1.前言 2.思路 3.代码 1.头文件 2.cpp文件 3.main 4.实现效果 1.前言 QComboBox每次只能选择一个,现项目中需要可以多次勾选.想实现一个带check功能的QCom ...

  5. QComboBox样式设置——Qt

    前言 我对qss只会一些简单的,所以每次都得查资料,自己调,好麻烦,特别是之前一篇博客关于菜单样式的设置.这次以为两者相似,结果不是的. 这个QComboBox下拉框的样式设置有稍微复杂,有些关键点得 ...

  6. 自定义多选QComboBox

    因项目需求,需要实现QComboBox的多选功能,如下图所示: 思路:QListWidget + QListWidgetItem + QCheckBox 代码如下 #ifndef MUTICOMBOB ...

  7. QComboBox下拉框文字如何在字体变大之后自适应高度

    一.简述 一般我们给QComboBox设置完字体之后,在显示上并没有什么问题如下图. a.正常状态 由于程序在最大化的时候,因为主窗口尺寸变大,需要整体改变所有控件的尺寸,文字的大小,所以在窗口最大化 ...

  8. Qt积少成多,QComboBox自定义信号槽

    阶段总结,QComboBox的信号槽连接: 1.默认名称 void on_cmbItemList_currentIndexChanged(const QString &text); 2.指定槽 ...

  9. QT设计中,样式不一致的问题(以QComboBox的下拉箭头为例)

    还是那句话,我是初次接触QT和C++,我的文章适合比我还小白的人看. 问题描述 最近在做C++的QGIS二次开发,遇到一个问题. 在QT Designer(QT Creater中同理)中进行设计,发现 ...

最新文章

  1. LED数码管仿真显示程序
  2. 使用Windows远程桌面(mstsc)通过RDP协议访问Ubuntu/Debian服务器
  3. ctb伺服驱动器说明书_青岛FANUC伺服电机364、453故障维修
  4. 留下方便自己找,,,求导
  5. leetcode最小面积_LeetCode—— 939. 最小面积矩形(JavaScript)
  6. 【Java】日期/事件字符串包含TZ
  7. php如何设置断点调试,使用 PHPStorm + Xdebug 实现断点调试
  8. 移动端HTML响应式布局之神奇的pt(自测99.99%与设计图一致)
  9. 蒙古族女孩鲍尔金娜的小说《紫茗红菱》
  10. 热敏电阻温度特性曲线_NTC热敏电阻如何选型
  11. ARKit:增强现实技术在美团到餐业务的实践
  12. Log4j 第三次发布漏洞补丁,漏洞或将长存
  13. mysql存储过程执行报错1175_mysql 数据库 存储过程执行报错的解决办法
  14. hihocoder1241 Best Route in a Grid
  15. html5做在线音乐,html5实现在线响应式音乐播放器
  16. 应用物理跨考计算机专业,应用物理学考研可跨专业
  17. swoft增加swagger(丝袜哥)
  18. 鱼骨图和甘特图图表合集PPT模板
  19. 大数据开发之Hive优化篇6-Hive on spark
  20. 物理机安装esxi系统

热门文章

  1. Python学习笔记:闭包与作用域
  2. 【BZOJ2758】Blinker的噩梦,扫描线+splay+链剖
  3. Intel Haswell/Broadwell架构/微架构/流水线 (5)-高速缓存存储器子系统
  4. NI myRIO-1900(ARM9)嵌入式小车2015.8-9
  5. MFC中常见控件的操作
  6. QObject::connect: No such signal QGraphicsView::mouseMovePoint(QPoint) in ***
  7. Unity Shader: Shader粒子广告牌
  8. python xlutils和openpyxl哪个好_Python-Excel 模块哪家强?
  9. 使用UE4发布安卓平台游戏
  10. UE4 编译虚幻引擎