小编个人主页详情<—请点击
小编个人gitee代码仓库<—请点击
Qt系列专栏<—请点击
倘若命中无此运,孤身亦可登昆仑,送给屏幕面前的读者朋友们和小编自己!
目录
- 前言
- 一、QGroupBox
- QGroupBox的属性
- QGroupBox的使用,基于QGroupBox模拟华莱士点餐
- 二、QTabWidget
- QTabWidget的属性
- QTabWidget的使用,标签页的新增和删除的实现
- 总结
前言
【Qt】常用控件(十六)QTreeWidget的属性和使用——书接上文 详情请点击<——
本文由小编为大家介绍——【Qt】常用控件(十七)QGroupBox,QTabWidget的属性和使用
一、QGroupBox
QGroupBox的属性
- 那么我们之前学习的多元素控件,也就是如下链接讲解的QListWidget列表控件,QTableWidget表格控件,QTreeWidget树形控件,那么里面包含的内容是一个一个自定义好的item对象,例如:QListWidget列表控件里面包含的就是一个一个的QListWidgetItem对象,QTableWidget表格控件里面包含的就是一个一个的QTableWidgetItem对象,QTreeWidget树形控件里面包含的就是一个一个的QTreeWidgetItem对象
【Qt】常用控件(十四)QListWidget的属性和使用,详情请点击<——
【Qt】常用控件(十五)QTableWidget的属性和使用,详情请点击<——
【Qt】常用控件(十六)QTreeWidget的属性和使用,详情请点击<—— - 那么我们接下来学习的容器类控件,容器类控件分为QGroupBox分组框,QTabWidget标签页,里面包含的内容是前面已经学过的各种控件,例如:QPushButton按钮控件,QLineEdit单行输入框控件,QLabel标签控件等,那么下面我们先来学习QGroupBox分组框
- QGroupBox可以实现一个带有标题的分组框,当一个界面比较复杂,包含了很多的控件的时候,那么使用分组框就可以把具有关联关系的控件,组织在一起作为一组,这样可以使界面更好看一点,是的,QGroupBox的作用就是让界面更好看一点,如上就是一个QGroupBox分组框,我们可以看到确实左上角是带有一个标题的,并且以一个淡灰色的框为界限进行分组,可以把其它的各种控件放到QGroupBox中,那么此时这些处于QGroupBox内部的控件的父元素就不再是this对应的窗口Widget了,而是QGroupBox
- 下面我们来学习一下QGroupBox的相关属性
(1)title,分组框的标题
(2)alignment,分组框内部内容的对齐方式,在第四点QLabel设置文本对齐方式中进行的讲解,详情请点击<——
(3)flag,是否为扁平模式,如果为扁平模式,那么原本QGroupBox的淡灰色的框就会消失左右下三面的边线,变成只有一条上面的边线,如果不为扁平模式,那么QGroupBox的就会有一个淡灰色的框
(4)checkable,是否可以选择,如果为true,那么如上,在title标题前面会多出一个可勾选的部分
(5)checked,描述分组框的选择状态,那么checked有效的前提是checkable为true,在checkable为true的前提下,如果勾选了,此时checked就为true表示分组框内的控件有效,也就是对应如上的左图,那么如果没有勾选,此时checked就为false表示分组框内的控件禁用,也就是对应如上的右图 - 那么值得注意的是QGroupBox分组框只是用来美化界面的这样的一个控件,并不涉及到和用户进行交互,所以QGroupBox分组框并没有相关的信号,至于要和用户进行交互,那么还要靠分组框内部的各种控件进行和用户交互的工作
QGroupBox的使用,基于QGroupBox模拟华莱士点餐
- 那么在之前的文章中,我们讲解了基于QComboBox模拟华莱士点餐 在第一点讲解的基于QComboBox模拟华莱士点餐,详情请点击<——,那么我们学习了QGroupBox,所以我们就可以将主食对应的下拉框,旋钮放到一组,将所以我们就可以将小食对应的下拉框,旋钮放到一组,将饮料对应的下拉框,旋钮放到一组,接下来我们采用图形化方式进行实现,所以接下来我们创建一个项目名为QGroupBox,基类为QWidget,派生类为Widget的项目,接下来我们点击ui文件,进入Qt Designer
- 所以此时我们拖拽左侧红框内的控件,然后调整成上图界面即可,objectName保持不变,将分组框的标题title修改为主食,那么我们从右上角可以看出,很明显此时QComboBox下拉框和QSpinBox微调框的父元素都是QGroupBox分组框,分组框的父元素是this指针对应的Widget窗口,所以当Widget窗口关闭的时候,会依次调用对象树下的元素的析构函数进行析构释放不会存在问题,并且由于对象树是一个树形结构,所以可以父元素,子元素这样一直向下延伸
- 我们知道,和主食一样,小食和饮料也需要各自将下拉框和微调框放在一组,所以此时我们简洁一点直接点击主食对应的QGroupBox分组框,然后ctrl+c复制主食的分组框,注意这里不能直接ctrl+v,因为此时我们点击了QGroupBox分组框,那么如果直接ctrl+v粘贴之后是粘贴在了主食对应的分组框内部,而我们期望的是粘贴在窗口Widget内部,所以此时我们点击Widget窗口,然后ctrl+v粘贴两次,将两个QGroupBox分组框的标题分别修改为小食,饮料
- 同样的,我们这里基于QGroupBox模拟华莱士点餐也就简单一点,仅仅使用文字,小编就不引入图标了,那么如上就是华莱士点餐的界面,那么小编仅仅将主食,小食,饮料对应 的名字添加到对应的下来框中
- 所以此时对于主食,小食,饮料对应的三个QGroupBox分组框内的下拉框,我们分别右击下拉框,点击编辑项目,然后添加对应的名称即可
运行结果如下
- 所以通过QGroupBox分组框此时主食就是一组,小食就是一组,饮料就是一组,并且分组框有有一个淡灰色的框,比较好看美观,我们可以自由的选择主食,小食,饮料,无误
- 那么接下来小编给主食,小食,饮料对应的QGroupBox分组框都勾选上flag扁平模式,所以此时如上,那么对于三个QGroupBox分组框来讲,此时原本QGroupBox的淡灰色的框就会消失左右下三面的边线,变成只有一条上面的边线
- 那么接下来小编给主食,小食,饮料对应的QGroupBox分组框都勾选上checkable,表示此时的QGroupBox可选,所以此时左上角就会有个勾选按钮,那么小编进行勾选,checked就为true表示分组框内的控件有效,那么此时我们也就可以对QGroupBox内的控件进行交互式的选择
- 那么接下来,小编取消勾选左上角,此时checked就为false表示分组框内的控件禁用,所以此时我们也就无法对QGroupBox内的控件进行交互式的选择了,即QGroupBox内的控件被禁用了
二、QTabWidget
QTabWidget的属性
- QTabWidget可以实现一个带有标签页的控件,那么对于每个标签页内部我们可以添加各种控件,进一步选中不同的标签页那么就可以显示不同的控件,进而具有不同的功能,下面小编不废话,我们先来看一下如何通过图形化方式的操作QTabWidget标签页控件,所以我们创建一个项目名为QTabWidget,基类为QWidget,派生类为Widget的项目,接下来我们点击ui文件,进入Qt Designer
- 所以此时我们拖拽左侧红框内的QTabWidget控件,然后调整成上图界面即可,objectName保持不变,此时默认就会有两个标签页,那么我们可以通过点击标签页对应的文本,例如Tab 1,Tab 2进行切换,其实也就类似于我们在电脑上使用的浏览器一样,那么每一个标签页其实都是一个QWidget,我们从右上角的类中可以看出
- 每一个标签页内部就是一个QWidget,同样的还可以通过另外一种方式查看,如上我们点击左侧的编辑,然后再点击ui文件,此时我们可以看到QTabWidget这个标签页控件内部包含两个标签页,这两个标签页就是QWidget类,也就是一个独立的QWidget窗口,所以此时才可以允许我们拖拽放置多个控件
- 那么接下来我们拖拽左侧Label控件,拖拽两次放到两个标签页中,将QLabel显示的文本设置为这是第一个标签页,这是第二个标签页
运行结果如下
- 那么我们可以点击标签页对应的文本Tab 1,Tab 2进行切换标签页,那么在不同的标签页上就可以有不同的显示,例如虽然都是QLabel,但是QLabel显示的文本不同,同样的我们也可以放置不同的控件,这里小编就不过多演示了
- 那么如果我想要进行标签页的新增该如何做呢?例如:我想要在标签页2后面新增一个标签页3,所以此时我们点击标签页2对应的文本Tab 2,然后右击标签页2,接下来点击插入页,然后点击在当前页之后,此时就可以新增一个标签页了
- 所以如上,此时已经新增了一个标签页3了,那么对于标签页3上显示的文本,那么我们点击标签页3,然后右侧将currentTabText修改为Tab 3,然后接下来在左侧拖拽一个QLabel到标签页3中,然后我们再将QLabel显示的文本修改为这是第三个标签页即可
运行结果如下
- 那么我们可以点击标签页对应的文本Tab 1,Tab 2,Tab 3进行切换标签页,那么在不同的标签页上就可以有不同的显示
- 那么如果我想要进行标签页的删除该如何做呢?例如:我想要删除标签页2,所以此时我们点击标签页2对应的文本Tab 2,然后右击标签页2,接下来点击3的页2,然后点击删除,此时就可以删除标签页2了
运行结果如下
- 那么此时标签页2就被删除了,那么我们可以点击标签页对应的文本Tab 1,Tab 3进行切换标签页,那么在不同的标签页上就可以有不同的显示
- 下面我们来学一下QTabWidget标签页控件的相关属性
(1) tabPosition,标签页文本所在的位置,那么我们可以设置成四个方向,如下
……(1)North,上方
……(2)South,下方,那么我们选中标签页控件,然后将右侧属性中的tabPosition选择为South,此时标签页对应的文本就显示在了标签页控件的下方
……(3)West,左侧,同样的,我们选择左侧,此时标签页对应的文本就显示在了标签控件的左侧,那么对于其它方向也都是类似的道理,读者友友可以自行选择
……(4)East,右侧
(2)currentIndex,当前选中的是第几个标签页,这里的计数是从0开始的
(3)currentTabText,当前选中的标签页的文本,这个小编在前面的标签页3已经进行了演示
(4)currentTabName,当前选中标签页的名字,和我们之前使用的objectName类似,例如:标签页的currentTabName是tab,那么我们在代码中就可以通过ui->tab的形式来进行访问到这个标签页
(5)currentTabIcon,当前选中的标签页的图标
(6)currentTabToolTip,当前选中的标签页的提示信息
(7)tabsCloseable,当前标签页是否可以关闭,那么如果勾选设置为true之后,此时界面上的QTabWidget的标签页对应的文本右侧会出现一个❌️,需要将❌️对应的信号结合对应的槽函数才能给标签页控件设定对应的关闭的操作
(8)movable,标签页是否可以移动,如果勾选设置为true,如上,那么此时标签页对应的文本就可以进行拖动调整标签页的顺序 - 下面我们来学一下QTabWidget标签页控件的相关信号
(1)currentChanged(int),在标签页发生切换时触发,参数为被点击的标签页的编号,标签页的编号是从0开始计数
(2)tabBarClicked(int),在点击标签页对应的文本时触发,参数为被点击的标签页的编号
(3)tabBarDoubleClicked(int),在双击标签页对应的文本时触发,参数为被点击的标签页的编号
(4)tabCloseRequest(int),在标签页被点击❌️关闭时触发,参数为被点击的标签页的编号,此时我们就可以给这个tabCloseRequest信号设置对应的槽函数用于实现对标签页关闭的操作
QTabWidget的使用,标签页的新增和删除的实现
- 所以在学习了QTabWidget的相关属性和使用之后,下面我们要实现一个标签页控件的新增和删除,那么此时界面上需要有一个QTabWidget标签页控件,提供两个按钮,一个按钮用于创建新的标签页,另一个按钮用于关闭当前选中的标签页,并且在切换标签页的时候,我们期望也可以感知到变化,所以接下来我们创建一个项目名为QTabWidget_2,基类为QWidget,派生类为Widget的项目,接下来我们点击ui文件,进入Qt Designer
- 所以此时我们拖拽左侧红框内的控件,然后调整成上图界面即可,objectName保持不变,接下来我们右击两个按钮,然后点击转到槽,接下来我们选择clicked信号,同样的由于我们也想在标签页发生切换的时候也感知到,所以此时我们右击QTabWidget,由于currentChanged信号可以在标签页发生切换的时候触发,符合我们的需求,所以接下来我们选择currentChanged信号,让Qt帮我们生成对应槽函数的声明和定义
#include"widget.h"#include"ui_widget.h"#include<QLabel>#include<QDebug>Widget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui->setupUi(this);QLabel*label1=newQLabel(ui->tab);label1->setText("标签页1");label1->resize(100,50);QLabel*label2=newQLabel(ui->tab_2);label2->setText("标签页2");label2->resize(100,50);}Widget::~Widget(){deleteui;}voidWidget::on_pushButton_clicked(){}voidWidget::on_pushButton_2_clicked(){}voidWidget::on_tabWidget_currentChanged(intindex){}- 所以此时在Widget构造函数中,我们先在每个标签页中创建一个QLabel,所以对于标签页1对应的currentTabName是tab,所以此时我们创建一个QLabel对象label1然后指定父元素是标签页1对应的tab,将label1挂接到对象树中,然后我们使用setText设置label1的文本是标签页1,接下来使用resize设置label的尺寸,那么宽度为100像素,高度为50像素
……(1)关于像素的讲解,在第八点,Qt坐标系的认识中的第13小点中进行的讲解,详情请点击<——
……(2)关于位置和尺寸,在第一点QWidget的geometry中的geometry中进行的讲解,详情请点击<—— - 同样的,对于标签页2对应的currentTabName是tab_2,所以我们同样创建一个QLabel对象label2然后指定父元素是标签页2对应的tab_2,将label2挂接到对象树中,同样的使用setText设置label2的文本是标签2
运行结果如下
- 那么此时标签页1和标签页2中就显示出了对应的QLabel标签对应的文本了,并且我们可以点击标签页对应的文本进而切换标签页1和标签页2
#include"widget.h"#include"ui_widget.h"#include<QLabel>#include<QDebug>Widget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui->setupUi(this);QLabel*label1=newQLabel(ui->tab);label1->setText("标签页1");label1->resize(100,50);QLabel*label2=newQLabel(ui->tab_2);label2->setText("标签页2");label2->resize(100,50);}Widget::~Widget(){deleteui;}voidWidget::on_pushButton_clicked(){intcount=ui->tabWidget->count();QWidget*w=newQWidget();ui->tabWidget->addTab(w,"Tab "+QString::number(count+1));QLabel*label=newQLabel(w);label->setText("标签页"+QString::number(count+1));label->resize(100,50);}voidWidget::on_pushButton_2_clicked(){}voidWidget::on_tabWidget_currentChanged(intindex){}- 接下来我们来编写新增标签页按钮对应的槽函数,那么首先我们使用count获取一下当前标签页控件中一共有几个标签页count,那么如果我们想要在标签页控件中新增一个标签页需要使用addTab这个方法,那么从之前的讲解中,我们已经知道标签页控件中的一个标签页本质上就是一个QWidget窗口,所以才允许我们放置多个控件
- 所以如果要在标签页控件中新增一个标签页需要给addTab传入一个QWidget对象,那么此时我们new一个QWidget对象w进行传入即可,那么对于addTab的第二个参数是用于指定标签页要显示的文本,那么标签页1显示的文本是Tab 1,标签页2显示的文本是Tab 2,所以假设此时我们要新增的是标签页3,那么对应要显示的文本就是Tab 3
- 此时标签页控件中对应的标签页是标签页1和标签页2,即标签页控件的数目count为2,所以此时我们就需要让count + 1才能为3,让"Tab "加上然后使用QString::number将count + 1对应的整数类型转换为QString类型之后传参给addTab的第二个参数
- 那么接下来我们创建一个QLabel用于显示文本,所以此时我们new一个QLabel对象,然后指定父对象是当前新创建的标签页,而当前新创建的标签页的本质就是一个QWidget窗口的对象w,所以此时我们给QLabel对象指定父元素为QWidget对象w即可,然后我们使用setText给QLabel对象设置文本,那么传入标签拼接上转化为字符串QString之后的count + 1即可
- 首先我们需要搞清楚count是当前标签页控件的标签页的数目,也就是我们新添加的标签页的编号,而编号的计数是从0开始的,也就类似于数组下标,所以我们将count + 1作为给用户看的标签页的编号可读性比较好,接下来使用resize设置QLabel对象的尺寸,那么宽度为100像素,高度为50像素
运行结果如下
- 所以此时点击新增标签页就可以新增标签页,那么标签页显示的文本,以及标签页下的QLabel对象显示的文本都没有问题
- 那么此时的结构就是最外层是一个Widget窗口,Widget窗口内部有多个控件,按钮,以及QTabWidget标签页控件
- 那么在QTabWidget标签页控件内部又含有多个标签页,这些标签页的本质是QWidget窗口,所以此时我们可以得出Widget窗口内部是可以嵌套QWidget窗口的
- 那么观察仔细的读者友友可能会发现,我们点击新增标签页的按钮新增了标签页之后,当前仍然停留在当前的标签页上,并没有自动转跳到新的标签页上面,所以如何才能实现添加了新的标签页之后可以自动跳转到新的标签页上面呢?如下
#include"widget.h"#include"ui_widget.h"#include<QLabel>#include<QDebug>Widget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui->setupUi(this);QLabel*label1=newQLabel(ui->tab);label1->setText("标签页1");label1->resize(100,50);QLabel*label2=newQLabel(ui->tab_2);label2->setText("标签页2");label2->resize(100,50);}Widget::~Widget(){deleteui;}voidWidget::on_pushButton_clicked(){intcount=ui->tabWidget->count();QWidget*w=newQWidget();ui->tabWidget->addTab(w,"Tab "+QString::number(count+1));QLabel*label=newQLabel(w);label->setText("标签页"+QString::number(count+1));label->resize(100,50);ui->tabWidget->setCurrentIndex(count);}voidWidget::on_pushButton_2_clicked(){}voidWidget::on_tabWidget_currentChanged(intindex){}- 那么我们可以让标签页控件调用setCurrentIndex,此时就可以实现标签页的切换,切换到指定的下标index位置处,那么我们新增的标签页的下标也就是标签页的编号,那么我们有吗?有的,新增的标签页的编号就是count,此时我们直接将count传入setCurrentIndex即可,同样的这里我们使用setCurrentWidget传入新增的标签页对象对应的QWidget对象w也可以实现标签页的切换,这里我们采用setCurrentIndex的方式
运行结果如下
- 所以此时我们再新增标签页,就可以自动切换到新增标签页对应的界面中了
- 那么接下来小编继续新增标签页,继续新增标签页,那么此时新增的标签页超过了界面的范围,不怕 ,QTabWidget会为我们自动添加向左,向右按钮,可以允许我们添加更多的标签页
#include"widget.h"#include"ui_widget.h"#include<QLabel>#include<QDebug>Widget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui->setupUi(this);QLabel*label1=newQLabel(ui->tab);label1->setText("标签页1");label1->resize(100,50);QLabel*label2=newQLabel(ui->tab_2);label2->setText("标签页2");label2->resize(100,50);}Widget::~Widget(){deleteui;}voidWidget::on_pushButton_clicked(){intcount=ui->tabWidget->count();QWidget*w=newQWidget();ui->tabWidget->addTab(w,"Tab "+QString::number(count+1));QLabel*label=newQLabel(w);label->setText("标签页"+QString::number(count+1));label->resize(100,50);ui->tabWidget->setCurrentIndex(count);}voidWidget::on_pushButton_2_clicked(){intindex=ui->tabWidget->currentIndex();if(index<0)return;ui->tabWidget->removeTab(index);}voidWidget::on_tabWidget_currentChanged(intindex){}- 那么接下来我们来实现删除标签页的clicked信号对应的槽函数,这里更完善一点应该叫做删除被选中的标签页,那么此时我们使用currentIndex获取用户当前选中的标签页编号index,那么默认都是由选中的标签页的,当标签页控件上的标签页被全部删除之后,此时用户就无法选中标签页了,此时currentIndex就会返回-1,那么此时我们进行判断,如果index小于0,那么说明此时标签页控件上的标签页全部都被删除了,无法进行标签页的删除了,所以此时我们直接return返回即可
- 那么走到下面说明,此时index大于0,用户选中了一个标签页,所以此时我们使用takeTab传入对应用户选中标签页对应的编号index进行删除标签页控件上被用户选中的标签页
运行结果如下
- 所以此时小编新增几个标签页,然后使用删除标签页按钮进行逐一的删除,没问题
- 那么接下来小编继续新增几个标签页,在这里值得注意的一点是第一个标签页的QLabel消失了,这里按道理来讲不应该消失,小编认为这可能是Qt的bug
- 接下来小编使用删除标签页按钮进行逐一的删除,没问题
#include"widget.h"#include"ui_widget.h"#include<QLabel>#include<QDebug>Widget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui->setupUi(this);QLabel*label1=newQLabel(ui->tab);label1->setText("标签页1");label1->resize(100,50);QLabel*label2=newQLabel(ui->tab_2);label2->setText("标签页2");label2->resize(100,50);}Widget::~Widget(){deleteui;}voidWidget::on_pushButton_clicked(){intcount=ui->tabWidget->count();QWidget*w=newQWidget();ui->tabWidget->addTab(w,"Tab "+QString::number(count+1));QLabel*label=newQLabel(w);label->setText("标签页"+QString::number(count+1));label->resize(100,50);ui->tabWidget->setCurrentIndex(count);}voidWidget::on_pushButton_2_clicked(){intindex=ui->tabWidget->currentIndex();if(index<0)return;ui->tabWidget->removeTab(index);}voidWidget::on_tabWidget_currentChanged(intindex){qDebug()<<"当前选中的标签页的编号是: "<<index<<'\n';}- 同样的由于我们也想在标签页发生切换的时候也感知到,而对于currentChanged信号可以在标签页发生切换的时候触发,所以此时对于currentChanged信号对应的槽函数,我们将当前选中的标签页的编号打印出来即可,而标签页的编号也就是currentChanged信号对应的槽函数的形参index,所以我们使用qDebug()进行打印日志即可
运行结果如下
- 所以此时小编一进行切换标签页控件上的标签页,我们就可以感知的到标签页的切换,并且进行对应日志的打印,无误
总结
以上就是今天的博客内容啦,希望对读者朋友们有帮助
水滴石穿,坚持就是胜利,读者朋友们可以点个关注
点赞收藏加关注,找到小编不迷路!