Qt之QComboBox定制
说起下拉框,想必大家都比较熟悉,在我们注册一些网站的时候,会出现大量的地区数据供我们选择,这个时候出现的就是下拉框列表,再比如字体选择的时候也是使用的下拉框,如图1所示。下拉框到处可见,作为一个图形库,qt也提供了QtComboBox类来供我们使用,但是有些时候简单的下拉列表已经满足不了我们的需求,如图2所示,是一个下拉表格,这个时候就需要我们自己定制一下QComboBox。
图1
图2
上边说了我们需求的变化,接下来我就讲述一下关于QComboBox定制的一些内容,本片文章我就只讲述两种常用的下拉选项控制,分别是列表和表格
一、列表的实现
首先我上一张qq的登录框,如图3所示,下拉列表里不仅仅是一个文字描述或者复选框,而是含有图片文字和关闭按钮的复杂窗口,那么这个时候简单的QComboBox是完成不了这项功能的,要做到像qq这样美观的功能是需要我们自己做一定的处理
图3
列表窗口定制步骤如下:
1、首先我们需要自定义一个窗口,上边有我们需要操作的内容,这个窗口讲会是QComboBox下拉框中的一项,我自己定义的类名为CActionContentWidget,头文件如下:
class CActionContentWidget : public QWidget
{
Q_OBJECT
signals:
void IconClicked();
void showText(const QString &); public:
CActionContentWidget(const QString & text, QWidget * parent = nullptr);
~CActionContentWidget(); public:
void SetContentText(const QString & text);//设置显示文字
void SetItemIcon(const QString & icon, const QString & hover);//设置图标 public:
void SetBackgroundRole(bool hover); protected:
virtual void enterEvent(QEvent *) Q_DECL_OVERRIDE;//暂时没用
virtual void leaveEvent(QEvent *) Q_DECL_OVERRIDE;//暂时没用
virtual bool eventFilter(QObject *, QEvent *) Q_DECL_OVERRIDE;
virtual void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE; virtual void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE; private:
void InitializeUI(); private:
bool m_Mouse_press = false;
QWidget * m_ContentWidget = nullptr;
QPushButton * m_ActIcon = nullptr;
QLabel * m_ActText = nullptr;
};
这个窗口支持鼠标hover事件,并且我自己实现了鼠标按下和弹起方法,为的是自己控制QComboBox下拉框的隐藏,接口SetBackgroundRole是控制窗口背景色变化的函数,由于enterEvent和leaveEvent方法在成为了代理窗口后,事件触发我自己也没有搞清楚是怎么回事,因此我使用了installEventFilter方法把该窗口的事件放到父窗口去处理,在窗口中判断鼠标当前位置和CActionContentWidget 窗口之间的关系来判断鼠标是否进入该窗口。
图4
2、如图4所示,是我实现的结果预览,接下来我们需要把定制的窗口放到QComboBox的下拉框中,代码如下:
class combobox : public QWidget
{
Q_OBJECT public:
combobox(QWidget *parent = );
~combobox(); protected:
virtual bool eventFilter(QObject *, QEvent *) Q_DECL_OVERRIDE; private:
void ConstructList();//列表定制
void ConstructTable();//表格定制 private:
Ui::comboboxClass ui;
};
ConstructList方法是列表的定制,也就是上图4所示的效果,ConstructTable方法内封装的是定制表格,后续我会讲解。
3、上边提到定制的窗口和鼠标位置的判断是在父窗口中进行的,那么接下来我就解释下父窗口的eventFIlter方法。代码比较简单,我就不一一进行解释了
bool combobox::eventFilter(QObject * watched, QEvent * event)
{
if (watched->inherits("QWidget") && event->type() == QEvent::Paint)
{
if (CActionContentWidget * actionItem = dynamic_cast<CActionContentWidget *>(watched))
{
if (actionItem->rect().contains(actionItem->mapFromGlobal(QCursor::pos())))
{
actionItem->SetBackgroundRole(true);
}
else
{
actionItem->SetBackgroundRole(false);
}
}
} return QWidget::eventFilter(watched, event);
}
4、ConstructList列表实现,代码如下:
void combobox::ConstructList()
{
QListWidget * listWidget = new QListWidget;
listWidget->setViewMode(QListView::ListMode); for (int i = ; i < ; i++)
{
CActionContentWidget * itemWidget = new CActionContentWidget("fawefawe");
connect(itemWidget, &CActionContentWidget::showText, this, [this, listWidget](const QString & text){
ui.comboBox->hidePopup();
if (ui.comboBox->isEditable())
{
ui.comboBox->setCurrentText(text);
}
else
{
for (int c = ; c < listWidget->count(); ++c)
{
CActionContentWidget * itemWidget = dynamic_cast<CActionContentWidget *>(listWidget->itemWidget(listWidget->item(c)));
if (itemWidget == sender())
{
ui.comboBox->setCurrentIndex(c);
}
}
}
});
itemWidget->SetItemIcon(":/combobox/Resources/icon1.jpg", ":/combobox/Resources/icon1.jpg");
itemWidget->setFixedHeight();
itemWidget->setFixedWidth();
QListWidgetItem * item = new QListWidgetItem(listWidget);
item->setText(QStringLiteral("%1").arg(i));
// item->setCheckState(Qt::Checked);
listWidget->setItemWidget(item, itemWidget);
listWidget->addItem(item);
itemWidget->installEventFilter(this);
} ui.comboBox->setModel(listWidget->model());
ui.comboBox->setView(listWidget);
ui.comboBox->setEditable(true);//是否支持下拉框可编辑
ui.comboBox->setMaxVisibleItems(); setStyleSheet("QComboBox{border:1px solid gray;}"
"QComboBox QAbstractItemView::item{height:45px;}" //下拉选项高度
"QComboBox::down-arrow{image:url(:/combobox/Resources/icon1.jpg);}" //下拉箭头
"QComboBox::drop-down{border:0px;}"); //下拉按钮
}
其中的setStyleSheet是用来设置下拉框中每一项的信息的,我们自己定制的窗口只是覆盖在原有窗口之上而已,原有的窗口还是存在的,因此我们的窗口必须和定制的窗口大小一样,负责会出现一些意外的情况。初次之外还需要注意的是:设置下拉框是否可编辑,如图5帮助文档所描述,QComboBox在可编辑状态下可以通过setCurrentText来设置displayText,但是如果不可编辑,他则会显示当前原有窗口的text,而非我们自己定制的窗口内容,因此我在showText信号的处理槽中,判断了下下拉框是否可编辑,并做相应的处理。
图5
还有几个设置下拉框属性的接口,我就不一一细说了,想了解的同学自己看帮助文档吧。其中setModel和setView是两居重点的代码,千万不能忘记,这两句代码是把QComboBox的视图和数据跟QListWidget绑定在一起了。QListWidget还支持ViewMode::IconMode这种现实模式,但是我们的下拉框定制用不到,因此我就不讲解这个了。
5、到此我们的列表定制就完成了。
二、表格实现
看明白了列表的实现,表格的实现就不在话下,不过我们列表的实现和表格的实现我在实现的时候还是有一定的区别的,有兴趣的同学可以接着往下看。首先就说下拉框的隐藏这一事件就和列表不一样,表格我是使用QTableWidget,内容使用QCheckBox,我自己重写了QCheckBox,并重新是了hitButton这个方法,因为当这个方法返回false时,鼠标点击不会选中/取消选中选择框,这个时候事件循环应该是传递到了父窗口上,而窗口把弹框隐藏了,这样做显然不满足我们的需求,有时候我们可能需要进行多个选择。说完需求之后我们来看代码。
1、首先我自己重写了QCheckBox,头文件代码如下:
class CheckBox : public QCheckBox
{
public:
CheckBox(QWidget * parent = nullptr) :QCheckBox(parent){}
~CheckBox(){};; protected:
virtual void checkStateSet() Q_DECL_OVERRIDE;
virtual bool hitButton(const QPoint & pos) const Q_DECL_OVERRIDE;
virtual void nextCheckState() Q_DECL_OVERRIDE;
};
大多数函数都是没有做处理,仅仅对hitButton方法做了重写,返回值直接返回true。这个时候就我们就可以进行多项选择,而弹框也不会消失。最终的实现效果如图6所示
图6
2、ConstructTable方法的实现如下:
void combobox::ConstructTable()
{
setStyleSheet("QComboBox QAbstractItemView {selection-background-color: transparent;}"); QTableWidget * tableWidget = new QTableWidget(, );
tableWidget->verticalHeader()->setVisible(false);
tableWidget->horizontalHeader()->setVisible(false);
tableWidget->setShowGrid(false);
for (int i = ; i < ; ++i)
{
tableWidget->setColumnWidth(i, );
tableWidget->setRowHeight(i, );
for (int j = ; j < ; ++j)
{
/* CActionContentWidget *itemWidget = new CActionContentWidget("fawefawe");
itemWidget->SetItemIcon(":/combobox/Resources/icon1.jpg", ":/combobox/Resources/icon1.jpg");
itemWidget->setFixedHeight(50);
itemWidget->setFixedWidth(50);*/
CheckBox * itemWidget = new CheckBox;
itemWidget->setFixedSize(, );
itemWidget->setStyleSheet(QString("QCheckBox {background-color:lightgray;}"
"QCheckBox:checked{background-color:white;}"));
connect(itemWidget, &QCheckBox::clicked, this, [this]{
QObject * sender = this->sender();
if (QCheckBox * item = dynamic_cast<QCheckBox *>(sender))
{
QString text = ui.comboBox->currentText();
if (text.isEmpty() == false)
{
if (item->isChecked())
{
if (text.split("|").indexOf(item->text()) == -)
{
text.append("|" + item->text());
}
}
else
{
text.remove("|" + item->text());
text.remove(item->text());
if (text.size() != && text.at() == '|')
{
text.remove(, );
}
}
}
else
{
if (item->isChecked())
{
text.append(item->text());
}
}
ui.comboBox->setCurrentText(text);
}
});
itemWidget->setText(QStringLiteral("好%1").arg(i));
itemWidget->setCheckable(true);
// tableWidget->setItem(i, j, new QTableWidgetItem(QStringLiteral("热分%1").arg(i)));
tableWidget->setCellWidget(i, j, itemWidget); itemWidget->installEventFilter(this);
}
} ui.comboBox->setModel(tableWidget->model());
ui.comboBox->setView(tableWidget);
// ui.comboBox->setEditable(true);
}
上边的代码都比较简单,我就不多了,我只说一个点,在设置表格列宽度的时候设置的为49,因为表格具有boder,如果设置50就会超出tableWidget,而出现左右滚动的现象
demo下载链接:http://download.csdn.net/detail/qq_30392343/9587529
很重要--转载声明
- 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords
- 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。
Qt之QComboBox定制的更多相关文章
- Qt之QComboBox定制(二)
上一篇文章Qt之QComboBox定制讲到了qt实现自定义的下拉框,该篇文章主要实现了列表式的下拉框,这一节我还将继续讲解QComboBox的定制,而这一节我将会讲述更高级的用法,不仅仅是下拉列表框, ...
- 通过Qt样式表定制程序外观(比较通俗易懂)
1. 何为Qt样式表[喝小酒的网摘]http://blog.hehehehehe.cn/a/10270.htm2. 样式表语法基础3. 方箱模型4. 前景与背景5. 创建可缩放样式6. 控制大小7. ...
- Qt之QComboBox(基本应用、代理设置)(转)
QComboBox下拉列表比较常用,用户可以通过选择不同的选项来实现不同的操作,如何实现自己的下拉列表呢? 很多人在问QComboBox如何设置选项的高度.代理等一些问题!今天就在此分享一下自己的一些 ...
- Qt之QComboBox(基本应用、代理设置)
QComboBox下来列表比较常用,用户可以通过选择不同的选项来实现不同的操作,如何实现自己的下拉列表呢? 很多人在问QComboBox如何设置选项的高度.代理等一些问题!今天就在此分享一下自己的一些 ...
- Qt中QComboBox中自定义界面使用stylesheet实现下拉按钮独立效果
使用QSS自定义控件界面时,QT中控件QCombobox含有两个子控件drop-down和down-arrow.一般而言,当改变QCombox时,很多效果都会出来,但是,针对下拉按钮和下拉图标的自定义 ...
- QT之QComboBox
1.addItems需要注意的事项: 1.在QT中设置maxVisibleItems的值,设置Items的最大可显示的值.(一般默认为10) 2.在每次需要清除已经添加的tems的时候需要注意,ui. ...
- 牛逼哄哄的Qt库
目录 一.有价值 - 好的网站 - 好的文章 二.Qt开源库-工具 - QtXlsx--excel读写库 三.Qt开源库-控件 - libqxt编译 - Qwt - QCustomPlot - 其他 ...
- csdn的下载链接token
qt之QComboBox定制 http://www.cnblogs.com/swarmbees/p/5710714.html http://download.csdn.net/detail/qq_30 ...
- QT定制有标题的扁平化下拉框控件
关键字:QT,QComboBox,QLineEdit,QListView,QPushButton,QMenu,QWidgetAction,setStyleSheet OS:Windows 7 方法一: ...
随机推荐
- CF987B - High School: Become Human
Year 2118. Androids are in mass production for decades now, and they do all the work for humans. But ...
- C# 动态调用WebService 3
using Microsoft.CSharp; using System; using System.CodeDom; using System.CodeDom.Compiler; using Sys ...
- Unity 图形处理(切分与拉伸)
素材的导入设置 1.导入的图片要设置为 Sprite 才能作为UI使用 2.如果需要进行切分,Sprite Mode 选择 Multiple 进行切分和拉伸设置 1.点击进入精灵编辑视图 2.点击按钮 ...
- String StringBuffer StringBulider 详细看https://www.cnblogs.com/su-feng
主要区别:运行速度和线程安全 StringBuilder > StringBuffer > String String最慢是因为字符串常量不可改变,例如 str +“cccc” 如果 ...
- RSP小组——团队冲刺博客六
RSP小组--团队冲刺博客六 冲刺日期:2018年12月18日 前言 各成员今日(12.18)完成的任务 李闻洲,赵乾宸代码合并 马瑞蕃图形后续支持,编写博客,燃尽图 蒋子行会议记录 各个成员的任务安 ...
- vscode设置中文语言
https://jingyan.baidu.com/article/7e44095377c9d12fc1e2ef5b.html
- go 可变参数
go 在参数列表中使用 ... 表示可变参数,例如: import "fmt" func Minimum(first int, others ...int) int { min : ...
- C#中添加log4net(日志文件)
1.先下载引用“log4net” 2.然后再App.config配置 3.添加一个LogHandler类 4.在Assemblyinfo类中添加配置的读取文件 5.运用日志文件 6.显示结果
- PHP 经典有趣的算法收集(面试题)
1.一群猴子排成一圈,按1,2,…,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去…,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫 ...
- php GD库快速消耗CPU资源漏洞 CVE-2018-5711测试
漏洞说明: 用一张GIF图片就可导致服务器发生崩溃直至宕机,在现实中非常容易利用. 影响版本: PHP 5 < 5.6.33 PHP 7.0 < 7.0.27 PHP 7.1 < 7 ...