摘要

本文基于QGroupBox扩展了一种可以伸缩的组合框,正常状态下,组合框处于收缩状态,内部的控件是隐藏的;需要的时候,可以将组合框进行伸展,并将内部控件显示出来。

正文

实现的代码比较简单,主要有以下几点:

1、该组合框继承于QGroupBox;

2、通过QSS将QGroupBox的默认Check图标替换;

3、通过QGroupBox的setFlat函数显示隐藏垂直边框

4、使用时,设置父窗口的layout的SizeConstraint为SetFixedSize,否则否则在ExtendedGroupBox收缩时,无法动态调整大小。

代码如下:

QSS样式:

QGroupBox#ExtendedGroupBox::indicator
{
width: 8px;
height: 8px;
} QGroupBox#ExtendedGroupBox::indicator:unchecked
{
image: url(:/icons/uncheck.png);
} QGroupBox#ExtendedGroupBox::indicator:checked
{
image: url(:/icons/check.png);
}
#ifndef EXTENDED_GROUP_BOX_H_
#define EXTENDED_GROUP_BOX_H_ #include <QGroupBox>
#include <QVector> class ExtendedGroupBox : public QGroupBox
{
Q_OBJECT public:
enum State
{
STATE_NORMAL,
STATE_EXPAND
}; public:
ExtendedGroupBox(QWidget *parent = nullptr, State state = STATE_NORMAL);
ExtendedGroupBox(const QString &title, QWidget *parent = nullptr, State state = STATE_NORMAL); private Q_SLOTS:
void onChecked(bool checked); public:
void addWidget(QWidget *widget);
State getState() const; private:
QVector<QWidget*> children_;
State state_;
}; #endif//EXTENDED_GROUP_BOX_H_
#include "ExtendedGroupBox.h"

ExtendedGroupBox::ExtendedGroupBox(QWidget *parent /*= nullptr*/, State state /*= STATE_NORMAL*/)
: QGroupBox(parent)
{
setObjectName("ExtendedGroupBox");
setCheckable(true);
state_ = state;
if (state_ == STATE_NORMAL)
{
//隐藏垂直边框
setFlat(true);
setChecked(false);
}
connect(this, SIGNAL(clicked(bool)), this, SLOT(onChecked(bool)));
} ExtendedGroupBox::ExtendedGroupBox(const QString &title, QWidget *parent /*= nullptr*/, State state /*= STATE_NORMAL*/)
: QGroupBox(title, parent)
{
setObjectName("ExtendedGroupBox");
setCheckable(true);
state_ = state;
if (state_ == STATE_NORMAL)
{
//隐藏垂直边框
setFlat(true);
setChecked(false);
}
connect(this, SIGNAL(clicked(bool)), this, SLOT(onChecked(bool)));
} void ExtendedGroupBox::addWidget(QWidget *widget)
{
if (widget != nullptr)
{
if (state_ == STATE_NORMAL)
{
widget->setVisible(false);
}
children_.push_back(widget);
}
} void ExtendedGroupBox::onChecked(bool checked)
{
if (checked)
{
//显示垂直边框
setFlat(false);
for (auto iter = children_.begin(); iter != children_.end(); ++iter)
{
(*iter)->setVisible(true);
}
state_ = STATE_EXPAND;
}
else
{
//隐藏垂直边框
setFlat(true);
for (auto iter = children_.begin(); iter != children_.end(); ++iter)
{
(*iter)->setVisible(false);
}
state_ = STATE_NORMAL;
}
} ExtendedGroupBox::State ExtendedGroupBox::getState() const
{
return state_;
}
#include "ExtendedGroupBox.h"

#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFormLayout>
#include <QCheckBox>
#include <QProgressBar>
#include <QFile> #include <QtWidgets/QApplication> int main(int argc, char *argv[])
{
QApplication a(argc, argv); QFile file(":/stylesheets/style.qss");
bool s = file.open(QFile::ReadOnly);
a.setStyleSheet(file.readAll());
file.close(); QDialog w;
QVBoxLayout *vbox_layout = new QVBoxLayout(); //设置窗口的layout的SizeConstraint为SetFixedSize,
//否则在ExtendedGroupBox收缩时,无法动态调整大小。
vbox_layout->setSizeConstraint(QLayout::SetFixedSize);
w.setLayout(vbox_layout); QGroupBox *setting_group_box = new QGroupBox(("Setting"));
QHBoxLayout *setting_layout = new QHBoxLayout();
setting_group_box->setLayout(setting_layout); QCheckBox *check_box1 = new QCheckBox(("CheckBox1"));
QCheckBox *check_box2 = new QCheckBox(("CheckBox2"));
QCheckBox *check_box3 = new QCheckBox(("CheckBox3"));
setting_layout->addWidget(check_box1);
setting_layout->addWidget(check_box2);
setting_layout->addWidget(check_box3); ExtendedGroupBox *advanced_setting_group_box = new ExtendedGroupBox(("Advanced Setting"), &w, ExtendedGroupBox::STATE_NORMAL);
QHBoxLayout *advanced_setting_layout = new QHBoxLayout();
advanced_setting_group_box->setLayout(advanced_setting_layout); QCheckBox *check_box4 = new QCheckBox(("CheckBox4"));
QCheckBox *check_box5 = new QCheckBox(("CheckBox5"));
QCheckBox *check_box6 = new QCheckBox(("CheckBox6"));
advanced_setting_layout->addWidget(check_box4);
advanced_setting_layout->addWidget(check_box5);
advanced_setting_layout->addWidget(check_box6); //将子控件添加到ExtendedGroupBox中
advanced_setting_group_box->addWidget(check_box4);
advanced_setting_group_box->addWidget(check_box5);
advanced_setting_group_box->addWidget(check_box6); vbox_layout->addWidget(setting_group_box);
vbox_layout->addWidget(advanced_setting_group_box); w.show();
return a.exec();
}

运行截图:

Qt自定义控件之可伸缩组合框(GroupBox)控件的更多相关文章

  1. (转载)VC/MFC 工具栏上动态添加组合框等控件的方法

    引言 工具条作为大多数标准的Windows应用程序的 一个重要组成部分,使其成为促进人机界面友好的一个重要工具.通过工具条极大方便了用户对程序的操作,但是在由Microsoft Visual C++开 ...

  2. VC/MFC 工具栏上动态添加组合框等控件的方法

    引言 工具条作为大多数标准的Windows应用程序的一个重要组成部分,使其成为促进人机界面友好的一个重要工具.通过工具条极大方便了用户对程序的操作,但是在由Microsoft Visual C++开发 ...

  3. 扩展GroupBox控件

    1.GroupBox的边框颜色可以自行设置: 2.GroupBox可以设置边框的为圆角: 3.设置GroupBox标题在控件中的位置. 4.设置GroupBox标题的字体和颜色. 具体实现步骤Pane ...

  4. 用MVC的辅助方法自定义了两个控件:“可编辑的下拉框控件”和“文本框日历控件”

    接触MVC也没多长时间,一开始学的时候绝得MVC结构比较清晰.后来入了门具体操作下来感觉MVC控件怎么这么少还不可以像ASP.net form那样拖拽.这样设计界面来,想我种以前没学过JS,Jquer ...

  5. Duilib实现GroupBox控件

    转载:http://blog.csdn.net/asd313346541/article/details/47055113 原作者的源码上说:右边线和下边线显示不出来: 后来经过调试研究测试猜测应该是 ...

  6. C#之菜单控件、主窗体打开子窗体、GroupBox控件使用

    一.背景 一年前有学习过C#,但没有在项目中去实际做APP,重新捡起来应用到项目中.我同事本来做好一个CANOPEN设备管理的界面,由于近期搜索了别人的开发的界面,我觉得有很多东西要重新安排,以及我已 ...

  7. win32: 文本编辑框(Edit)控件响应事件

    过去几年,关于文本编辑框(Edit)控件的响应事件,我都是在主程序 while(GetMessage(&messages, NULL, 0, 0)) { ... } 捕获. 总感觉这种方式让人 ...

  8. WPF自定义控件(二)の重写原生控件样式模板

    话外篇: 要写一个圆形控件,用Clip,重写模板,去除样式引用圆形图片可以有这三种方式. 开发过程中,我们有时候用WPF原生的控件就能实现自己的需求,但是样式.风格并不能满足我们的需求,那么我们该怎么 ...

  9. winform groupbox控件放到窗体中间位置

    1. 在Form中放一个控件,让其在启动时始终居中 int gLeft = this.Width / 2 - groupControl1.Width / 2; int gTop = this.Heig ...

随机推荐

  1. Solution -「SDOI 2017」「洛谷 P3784」遗忘的集合

    \(\mathcal{Description}\)   Link.   给定 \(\{f_1,f_2,\cdots,f_n\}\),素数 \(p\).求字典序最小的 \(\{a_1,a_2,\cdot ...

  2. Spring 控制反转和依赖注入

    控制反转的类型 控制反转(IOC)旨在提供一种更简单的机制,来设置组件的依赖项,并在整个生命周期管理这些依赖项.通常,控制反转可以分成两种子类型:依赖注入(DI)和依赖查找(DL),这些子类型各自又可 ...

  3. 内省机制(操作javaBean的信息)

    内省机制(操作javaBean的信息) ----是不是联想到了反射机制了哈,这两者有什么区别呢? 1.内省机制和反射机制的联系 ■ 其实内省机制也是通过反射来实现的,而反射是对一切类都适合去动态获取类 ...

  4. pytest--mark基本使用(主要通过pytest.ini文件注册标签名,对用例进行标记分组)

    1.pytest中的mark介绍 mark主要用于在测试用例/测试类中给用例打标记(只能使用已注册的标记 名),实现测试分组功能,并能和其它插件配合设置测试方法执行顺序等.如下 图,现在需要只执行红色 ...

  5. Invoke and BeginInvoke

    原博客地址:http://www.cnblogs.com/worldreason/archive/2008/06/09/1216127.html 写的真的很好! 在Invoke或者BeginInvok ...

  6. elasticsearch7.8.0,kibana7.8.0安装

    目录 Windows下安装Elasticsearch Linux下安装Elasticsearch docker下安装Elasticsearch Kibana安装 chrome ElasticSearc ...

  7. node-java的使用及源码分析

    上篇文章简单提了下node调用java的方法但也只属于基本提了下怎么输出helloworld的层度,这次将提供一些案例和源码分析让我们更好地了解如何使用node-java库. 前置知识: 1.桥接模式 ...

  8. Chrome:查看用户代理User-Agent

    用户代理(User-Agent)是浏览器客户端与服务器交互时的重要信息之一,用于帮助服务器识别请求用户的浏览器类别,以便于网站发送相应的网页数据. 用户代理数据包括:操作系统标识.加密等级标识和浏览器 ...

  9. c语言刷 设计题合计

    355. 设计推特 #define MAX_LEN 512 struct User { int userId; int followee[MAX_LEN]; // 散列表,0/1,1表示这个user被 ...

  10. 发现Spring事务的一个实锤bug,官方还拒不承认?你来评评理...

    你好呀,我是歪歪. 事情是这样的,上周我正在全神贯注的摸鱼,然后有个小伙伴给我发来微信消息,提出了自己关于事务的一个疑问,并配上两段代码: 先说结论:我认为这是 Spring 事务的一个 bug.但是 ...