组合框里添加复选框的方法(使用勾选的假象,用图片代替而已,并非QT原生支持)
组合框可以看作是列表框和文本框的组合,因其占据的空间少,使用操作方便,常被界面设计人员用于界面开发设计中,在有限个输入的条件下,组合框常用来代替文本框,这样从用户使用角度来看,更趋人性化,所见即所得。然好的控件永远敢不上应用的步伐,有时常规控件并不能满足应用的需要,经常需要在现有的控件上做扩展。有些应用需要在组合框的列表框的每一项前加复选框,以便可以控制列表框每一项的状态(选中还是未选中),显然现有的组合框(列表框+文本框的组合)不能满足应用要求。那么怎么得到一个超强组合框(列表框+文本框+复选框的组合)呢?这种组合框既要有一般组合框的功能,又要有复选框的功能。接下来,我将介绍一种在组合框里添加复选框的方法:
先贴出图,让大家一睹为快,接下来介绍下它的实现方式,首先看看QComboBox增加项的方法:
- void addItem(const QIcon &icon, const QString &text, const QVariant &userData = QVariant())
第一个参数在项的前面加图片,第二个参数是项的名字,第三个参数可以给项一个私有数据,如保存项的状态。
从addItem方法,第一个参数可以在项前添加图片,第三个参数可以保存项的状态,那么我们可以准备两幅图片,1幅是没打钩的复选框,1幅是打钩的复选框,用第三个参数来保存复选框的状态,当第三个参数的状态为选择的状态时,显示打勾的复选框,否则显示不打钩的复选框。看起来这种方法可行,不过要实现复选框功能,还的解决以下几个问题:
1.当鼠标单击复选框图片时,需要计算鼠标是单击了那一项
2.确定了单击的项后,还要能取出该项的状态(通过addItem的第三个参数设置的状态)
3.再根据项的状态,更新该项的图标,并且更改该项的状态
前面3点实现后,复选框的基本功能就实现了,当鼠标在复选框上单击时,复选框的图标就会改变,若之前是选中状态,则单击后变为非选中状态,若之前是非选中状态,则单击后变为选中状态。但是还没有完,这样的复选框还是个中看不中用的复选框,还需要给外界提供一个接口,当复选框状态改变了,要提供1个通知接口,要不然使用该控件的用户就必须定时轮询所有的复选框的状态了,很显然这不是一个好的设计。
4.当项状态改变了,还要能对外提供1个项状态改变的接口。
有了上面的思路,下面来看看实现:
- 头文件
- #ifndef _CHECK_COMBOX_H
- #define _CHECK_COMBOX_H
- #include <qcombobox.h>
- class CCheckCombox : public QComboBox
- {
- Q_OBJECT
- public:
- CCheckCombox(QWidget *parent = NULL);
- void appendItem(const QString &text, bool bChecked);
- void hidePopup();
- protected:
- void mousePressEvent(QMouseEvent *e);
- signals:
- void checkedStateChange(int index, bool bChecked);
- private:
- void updateIndexStatus(int index);
- };
- #endif
我们定义了1个类CCheckCombox,派生自QComboBox。通过appendItem来给组合框增加项;hidePopup是QComboBox的虚函数,该函数实现组合框的列表框隐藏,我们的目的是,当鼠标单击列表项前的复选框时,不让列表框隐藏,只更改复选的图标,所以需要重载hidePopup;mousePressEvent 是鼠标单击事件, 这也是父类的的虚函数,重载它是为了确定鼠标是否单击了复选框,单击了就要更改复选框状态;updateIndexStatus大家应该猜到了,该函数就是实现更改项的状态的函数;checkedStateChange这是一个信号,负责在项状态改变的时候,发送项状态改变信号,提供给外界一个应用接口。下面我们来看看实现:
- 源文件
- #include "checkcombox.h"
- #include <QMouseEvent>
- #include <qdebug.h>
- #include <qabstractitemview.h>
- CCheckCombox::CCheckCombox(QWidget *parent) : QComboBox(parent)
- {
- }
- void CCheckCombox::appendItem(const QString &text, bool bChecked)
- {
- QIcon icon;
- if (bChecked)
- icon.addFile(":/check.png");
- else
- icon.addFile(":/uncheck.png");
- addItem(icon, text, bChecked);
- }
- void CCheckCombox::updateIndexStatus(int index)
- {
- bool bChecked = itemData(index).toBool();
- if (bChecked)
- setItemIcon(index, QIcon(":/uncheck.png"));
- else
- setItemIcon(index, QIcon(":/check.png"));
- setItemData(index, !bChecked);
- emit checkedStateChange(index, !bChecked);
- }
- void CCheckCombox::mousePressEvent(QMouseEvent *e)
- {
- int x = e->pos().x();
- int iconWidth = iconSize().width();
- if (x <= iconWidth)
- {
- int index = currentIndex();
- updateIndexStatus(index);
- }
- else
- QComboBox::mousePressEvent(e);
- }
- void CCheckCombox::hidePopup()
- {
- int iconW = iconSize().width();
- int x = QCursor::pos().x() - mapToGlobal(geometry().topLeft()).x() + geometry().x();
- int index = view()->selectionModel()->currentIndex().row();
- if (x >= 0 && x <= iconW)
- {
- updateIndexStatus(index);
- }
- else
- {
- QComboBox::hidePopup();
- }
- }
下面看看应用代码:
- #include "checkcombox.h"
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QWidget widget(NULL, Qt::Tool);
- widget.setWindowTitle("My ComboBox");
- CCheckCombox combox;
- QHBoxLayout *phLayout = new QHBoxLayout(&widget);
- phLayout->addWidget(&combox);
- widget.setLayout(phLayout);
- combox.appendItem("1", false);
- combox.appendItem("2", true);
- combox.appendItem("3", true);
- combox.appendItem("4", true);
- combox.appendItem("5", true);
- widget.show();
- return a.exec();
- }
http://blog.csdn.net/rabinsong/article/details/9007283
组合框里添加复选框的方法(使用勾选的假象,用图片代替而已,并非QT原生支持)的更多相关文章
- 给Repeater控件里添加序号的5种方法
Repeater是我们经常用的一个显示数据集的数据控件,经常我们希望在数据前显示数据的序号,那么我们该怎么为Repeater控件添加序号呢?下面编辑为大家介绍几种常用的为Repeater控件添加序号的 ...
- visual studio 2019工具里添加开发中命令提示符的方法
最新新装了visual studio 2019,发现默认的没有开发者命令提示符 现将添加步骤描述如下: 从VS2019菜单选择"Tools",然后选择"外部工具" ...
- CSS 文本框里添加按钮的实现
有很多人做界面会经常发现设计师设计出这样的界面: 咋一看是一个文本框里加了一个按钮,经过谷歌之后,未发现在文本框里可以添加按钮. 但可以通过div来实现它. 我的做法是先做一个大小的div,然后用带里 ...
- 怎样使一个INPUT框里的文字在框被点击后自动全选或清除?
$("#smsContent").focus(function(){ this.select(); }); <input name="keywords" ...
- 【Eclipse使用】在eclipse里添加源文件和Api的方法
一.源代码添加 你的JDK安装目录下%Java_home%/src.zip文件就是源码,解压缩找到对应包下面的类即可. 如果是Eclipse开发,ctr+鼠标左击,出现不了源码的话,在弹出的视图中点击 ...
- eclipse:不能在tomcat里添加一个项目的解决方法
Cannot add a project to a tomcat server in eclipse You didn't create your project as "Dynamic W ...
- Java获取后台数据,动态生成多行多列复选框
本例目标: 获取后台数据集合,将集合的某个字段,比如:姓名,以复选框形式显示在HTML页面 应用场景: 获取数据库的人员姓名,将其显示在页面,供多项选择 效果如下: 一.后台 查询数据库,返回List ...
- angularJS批量删除 品优购删除品牌(通用复选框批量选中删除解决思路)
思路: 一步:在点击复选框时维护变量数组 在js中定义一个数组变量, 给复选框添加点击动作, 在动作中判断当前复选框是否为选中状态(即点击后复选框的是否选中状态), 若为选中状态,则向数组中添加选中的 ...
- 【MFC学习笔记-作业5-小数据库】【单选框,复选框,滚动条,列表框】
界面已经实现完毕. 要完成的操作就是1.性别分组(2选1) 2.属性勾选 3.年龄通过滚动条调整 4.职称通过下方的列表框选择 5.输入姓名 6.存入左方的列表框 7.当选择左方列表框的人时,可以显示 ...
随机推荐
- Linux下多任务间通信和同步-消息队列
Linux下多任务间通信和同步-消息队列 嵌入式开发交流群280352802,欢迎加入! 简介 消息队列简称为队列.消息队列就是一些消息的列表.用户可以在消息队列中添加消息和读取消息等.从这点上看,消 ...
- verilog 随笔
不是说你在代码里定义一个reg型变量,综合器就会综合处一个寄存器来,case必须在always块里,always里面的被赋值变量必须是reg型,这是语法的规定,只能遵守.写代码的时候不要加入触发器(不 ...
- INFOQ几篇论文
http://www.infoq.com/cn/articles/java-profiling-with-open-source http://www.infoq.com/cn/articles/Vi ...
- SDL介绍
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成.SDL提供了数种控制图像.声音.输出入的函数,让开发者只要用相同或是相似的代码就可以开发 ...
- 10.30 NFLS-NOIP模拟赛 解题报告
总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没 ...
- 如何制作一个类似Tiny Wings的游戏(2) Cocos2d-x 2.1.4
在第二篇<如何制作一个类似Tiny Wings的游戏>基础上,增加添加主角,并且使用Box2D来模拟主角移动,原文<How To Create A Game Like Tiny Wi ...
- jstack命令使用
概述 jstack可用于导出java运用程序的线程堆栈.其基本使用语法为: jstack [-l] pid -l 选项用于打印锁的额外信息. 使用演示样例 以下这段代码执行之后会出现死锁现象(由于线程 ...
- hibernate环境配置和使用
一.hibernate简单介绍 Hibernate是一个开放源码的对象关系映射框架,它对JDBC进行了很轻量级的对象封装,使得Java程序猿能够随心所欲的使用对象编程思维 ...
- Objective-C中的@dynamic
一.@dynamic与@synthesize的区别 @property有两个对应的词,一个是@synthesize,一个是@dynamic.如果@synthesize和@dynamic都没写,那么默认 ...
- 新辰:4G时代怎样利用手机进行移动APP营销?
未来的时代是4G时代,新辰手机用户的搜索量不在电脑端之下.那么,我们要怎样用手机进行营销呢?手机站点的竞价文章,要怎样去写比較好?手机站点要做专题吗?手机站点的优化思路在哪里?手机的系统不同,在不同的 ...