Qt实现小功能之复杂抽屉效果详解

 更新时间:2022年10月09日 11:33:57   作者:中国好公民st  
在Qt自带的控件中,也存在抽屉控件:QToolBar。但是,该控件有个缺点:一次只能展开一个抽屉信息,无法实现多个展开。所以本文将自定义实现复杂抽屉效果,需要的可以参考一下

在Qt自带的控件中,也存在抽屉控件:QToolBar。但是,该控件有个缺点:一次只能展开一个抽屉信息,无法实现多个展开。为此,实现了如下效果的程序:

下面对这种实现效果进行讲解~

功能讲解

开发环境:VS2017 + Qt5.14.2 64位

实现的核心技术:

1:QScrollArea的应用。

2:垂直布局的应用。

根据展示效果可以发现:一个标题下面对应了一个显示窗口,标题的下拉按钮控制了粉色窗口的显示和隐藏。

接下来,由内向外进行实现。

自定义标题widget

类名:QSingleTitleWidget

代表了每一个单独的标题窗口。包含了两个控件:QLabel、QCheckBox,分别展示标题名称以及控制是否展示对应的内容窗口

标题名称控件的创建

QString qsLabelStyle = "QLabel{color:#333333; font-family:Microsoft YaHei UI; font-size:18px;} QLabel{background-color: transparent}";
m_labTitle = new QLabel(this);
m_labTitle->setGeometry(10, 0, 200, 60);
m_labTitle->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
m_labTitle->setStyleSheet(qsLabelStyle);
m_labTitle->show();

QCheckBox控件的创建

QString qsCheckStyle = "QCheckBox{color:#333333;font-family:Microsoft YaHei UI;font-size:14px;}"
"QCheckBox::indicator::checked{image:url(:/QMultipleToolBarWidget/image/jd_zk_s.png)}"
"QCheckBox::indicator::unchecked{image:url(:/QMultipleToolBarWidget/image/jd_sq_n.png)}"; 
m_check = new QCheckBox(this);
m_check->setGeometry(500, 5, 50, 60);
m_check->setStyleSheet(qsCheckStyle);
connect(m_check, &QCheckBox::clicked, this, &QSingleTitleWidget::OnCheckShowState);
m_check->show();
m_check->setChecked(false);

在标题类(QSingleTitleWidget)中需要实现QCheckBox的响应消息,通知外界该标题类对应的内容类是显示还是隐藏状态。

"setChecked(false)":默认窗口一创建就让粉色窗口处于隐藏状态。

对于QCheckBox的消息的实现,如下:

void QSingleTitleWidget::OnCheckShowState(bool checked /*= false*/)
{
	emit Msg_SendShowState(m_nNum, checked);
}

其中,m_nNum是当前标题窗口的编号,在通知外界的同时也需要告诉外界,是哪个窗口发生了变化!

补充一点:在QSingleTitleWidget类中也可以不实现QCheckBox响应消息,直接使用QWidget::mousePressEvent消息做处理,这里不再详细说明!

自定义内容Widget

类名:QSingleContentWidget

代表了每一个单独的内容窗口。仅有一个控件:QLabel,只是用于提示窗口的高度。

其实在实际开发中,可以展示更丰富的内容,这里只是展示了不同高度。

创建显示高度描述控件

QString qsLabelStyle = "QLabel{color:#333333; font-family:Microsoft YaHei UI; font-size:18px;} QLabel{background-color: transparent}";
m_labContent = new QLabel(this);
m_labContent->setStyleSheet(qsLabelStyle);
m_labContent->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
m_labContent->show();

设置具体的高度值

void QSingleContentWidget::SetContent(int nHeight)
{
	QString qsContent = QStringLiteral("当前窗口高度是:") + QString::number(nHeight);
	m_labContent->setGeometry(10, 10, 540, nHeight-20);
	m_labContent->setText(qsContent);
}

以上1、2两部分内容分别描述了标题widget、内容widget,下面需要创建一个承载这些内容的widget载体,将在QScrollArea中使用。

QScrollArea中widget实现

类名:QScrollAreaWidget

该类是一个承载多个标题、内容的widget,也是直接由外部调用的类。

假设:传入一个std::vector<int>的容器,容器的多少大小代表的是标题的个数,int值是随机生成的高度值。

但是,到了真正业务应用中时,这里的int没准就是一个结构体,或者是一个数据指针,无论是什么,处理方式都是一样的。

对外开放接口:

void QScrollAreaWidget::SetScrollAreaData(std::vector<int> vetWidget)
{
    //数据处理
}

根据vetWidget的大小创建出对应的数据组(一个标题、一个内容)

直接上全部代码~

int nTop = 0;
for (int i = 0; i < vetWidget.size(); i++)
{
	//创建:标题
	QSingleTitleWidget *widgetTitle = new QSingleTitleWidget(this);
	widgetTitle->setFixedSize(560, 60);
	widgetTitle->SetTitleContent(i);
	bool bShowState = i == 0 ? true : false;
	widgetTitle->SetShowState(bShowState);
	widgetTitle->show();
	connect(widgetTitle, &QSingleTitleWidget::Msg_SendShowState, this, &QScrollAreaWidget::MsgReceivedTitleControlShowState);
	m_vetTitleWidget.push_back(widgetTitle);
	m_layout.addWidget(widgetTitle);
	nTop += 60 + 5;

	//创建:内容
	QSingleContentWidget *widgetContent = new QSingleContentWidget(this);
	widgetContent->setFixedSize(QSize(560, vetWidget[i]));
	widgetContent->SetContent(vetWidget[i]);
	if (bShowState == true)
	{
		widgetContent->show();
		nTop += vetWidget[i] + 5;
	}
	else
	{
		widgetContent->hide();
	}
	m_mapContentWidget.insert(std::make_pair(i, widgetContent));
	m_layout.addWidget(widgetContent);

}
m_layout.addStretch(0);
m_layout.setSpacing(5);
this->setLayout(&m_layout);

m_nTotalHeight = nTop;

this->setFixedSize(QSize(560, nTop));

代码讲解:

1:创建标题类:QSingleTitleWidget、创建内容类:QSingleContentWidget。

这两个类是一对一对应的。其中,这里有个小逻辑处理,当编号是0时(也就是第一组数据时)默认处于显示状态。

采用了三目运算符,方便简单:bool bShowState = i == 0 ? true : false;

并且,在创建QSingleContentWidget类时,根据是否显示状态来控件该类是否显示。

2:消息处理

之前在QSingleTitleWidget类中发送了一个QCheckBox的消息,在这里就运用到该消息了。

Msg_SendShowState参数值=true时,代表展示QSingleContentWidget类内容;反之,隐藏QSingleContentWidget类的内容。

3:垂直布局应用

每创建一个新的widget,需要将widget添加到布局中:m_layout.addWidget(widgetTitle);

最后,需要在当前类中绑定布局:this->setLayout(&m_layout);

4:nTop值的意义

每创建一个类都需要对nTop进行追加,主要是为了扩大QScrollArea子窗口widget的大小,其实在使用布局后不使用也没有关系,但是为了能够让我们控制widget的高度,最好主动进行设置。

QScrollArea子窗口的提升

从Qt Designer中拖出来的QScrollArea控件,默认会自带一个widget子控件,上述3下的功能就是对子控件的重写,那么该如何绑定呢?

选中提升后,出现下面页面

红框里面就是需要提升的类文件以及类名。

注意:设置了提升的类名称后,默认头文件会自动添加,但是该头文件是不区分大小写!这里一定要改成与实际的头文件名称保持一致!

刚开始做的时候未区分大小写,结果找了半天才找到原因,这也跟Qt版本有关系,最好与我们提升的类一一对应!

到此这篇关于Qt实现小功能之复杂抽屉效果详解的文章就介绍到这了,更多相关Qt复杂抽屉效果内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c# 实现获取汉字十六进制Unicode编码字符串的实例

    c# 实现获取汉字十六进制Unicode编码字符串的实例

    下面小编就为大家带来一篇c# 实现获取汉字十六进制Unicode编码字符串的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • FFmpeg中avfilter模块的介绍与使用

    FFmpeg中avfilter模块的介绍与使用

    FFmpeg中的libavfilter模块(或库)用于filter(过滤器), filter可以有多个输入和多个输出,下面就跟随小编一起简单学习一下它的巨日使用吧
    2023-08-08
  • C语言编程函数指针入门精讲教程

    C语言编程函数指针入门精讲教程

    大家在C语言的学习中一定会接触指针这样一个东西,而指针也是新手路上一定要消灭的boss,如果以后还要学习Java的同学更是要注重指针的学习,希望能够有所帮助
    2021-10-10
  • C++设计模式之策略模式

    C++设计模式之策略模式

    这篇文章主要介绍了C++设计模式之策略模式,本文讲解了什么是策略模式、策略模式的使用场合、策略模式的代码实例等内容,需要的朋友可以参考下
    2014-10-10
  • C++抛出和接收异常的顺序

    C++抛出和接收异常的顺序

    这篇文章主要介绍了C++抛出和接收异常的顺序,帮助大家更好的理解和学习C++,感兴趣的朋友可以了解下
    2020-08-08
  • Qt进程和线程QProcess和QThread的使用

    Qt进程和线程QProcess和QThread的使用

    本文主要介绍了Qt进程和线程QProcess和QThread的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • c语言实现两个值互相交换的函数

    c语言实现两个值互相交换的函数

    本文通过代码给大家介绍c语言实现两个值互相交换的函数,通过实例代码给大家讲解的很详细,具有一定的参考借鉴价值,对c语言两个值互换函数相关知识感兴趣的朋友一起看看吧
    2021-05-05
  • 详解桶排序算法的思路及C++编程中的代码实现

    详解桶排序算法的思路及C++编程中的代码实现

    桶排序即是先把每个桶中的元素进行排序然后遍历桶依次列出元素的算法,桶排序在元素较少的情况下很高效,以下我们就来详解桶排序算法的思路及C++编程中的代码实现:
    2016-07-07
  • C或C++报错:ld returned 1 exit status报错的原因及解决方法

    C或C++报错:ld returned 1 exit status报错的原因及解

    这篇文章主要介绍了C或C++报错:ld returned 1 exit status报错的原因及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-02-02
  • C++类与对象的详细说明2

    C++类与对象的详细说明2

    这篇文章主要为大家详细介绍了C++的类与对象,使用数据库,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02

最新评论