《QT学习第三篇:多元素、容器类控件与布局管理器、QT窗口》

**前引:**Qt框架中常用控件的使用方法,主要包括: 多元素控件:ListWidget纵向列表、TableWidget表格、QTreeWidget树形控件的创建与操作; 容器类控件:GroupBox分组框和TabWidget标签页的使用; 布局管理器:垂直/水平/网格布局、表单布局及空白间隔的设置; QT窗口组件:详细讲解了菜单栏、工具栏、状态栏、滑动窗口的创建方法; 对话框应用:包括代码/图形化创建方式、模态与非模态对话框,以及QMessageBox提示框、QColorDialog颜色框等派生对话框的使用!

目录

一、多元素控件

(1)ListWidget纵向列表

(2)TableWidget表格

(3)QTreeWidget树形控件

二、容器类控件

(1)GroupBox分组框

(2)TabWidget标签页

[(3)Scroll Area滚蛋框](#(3)Scroll Area滚蛋框)

[(4)Tool Box折叠框](#(4)Tool Box折叠框)

(5)StackedWidget堆叠框

(6)Widget与Frame窗口容器

三、布局管理器

(1)垂直/水平/网格/表格布局

(2)表单布局

(3)空白间隔

四、弹簧

五、QT窗口

QT窗口介绍

六、菜单栏

(1)创建菜单栏

(2)创建菜单

(3)创建菜单选项

(4)设置快捷键

(5)举例

(6)子菜单

(7)分割线

(8)添加图标

七、工具栏

八、状态栏

九、滑动窗口

十、对话框

(1)代码创建

(2)图形化创建

(3)模态与非模态

(4)QDialog派生对话框

(1)QMessageBox提示框

(2)QColorDialog颜色框

(3)QFileDialog文件操作

(4)QFontDialog字体框

(5)QInputDialog条目框


一、多元素控件

(1)ListWidget纵向列表

使⽤ QListWidget 能够显⽰⼀个纵向的列表,例如:

常用成员函数:

addItem(const QString& label):往列表中添加元素

takeItem(int row):删除指定行的元素

currentRow:获取当前选中的行数(从0开始建立索引)

常用信号:

currentRowChanged(int):返回当前选中元素的行数

设置文本样式:这个就不介绍了

例如:制作一个"新增"元素、"删除"指定行元素的方法实现

(2)TableWidget表格

在 ui 中有这样一个控件 Table Widget ,表格模型,如图:

常用成员函数:

rowCount():获取当前的行数

columnCount():获取当前的列数

currentRow():返回被选中的元素是第几行

currentColumn():返回被选中的元素是第几列

insertRow(int row):在第几行处插入新行

insertColumn(int column):在第几列处插入新列

removeRow(int row):删除第几行

removeColumn(int column):删除第几列

setItem(int row , int column , QTableWidget*):对指定行、列增加元素

setHorizontalHeaderItem(int column , QTableWidget*):设置指定列的表头

(第二个参数是一个指向 QTableWidgetItem 类型的指针,可以传各种参数)

setVerticalHeaderItem(int row ,QTableWidget*):设置指定行的表头

(第二个参数是一个指向 QTableWidgetItem 类型的指针,可以传各种参数)

快捷方式:一次性插入多个列的表头

cpp 复制代码
// 语法格式
tableWidget->setColumnCount(列数); // 必须先设置列数,即有几列
tableWidget->setHorizontalHeaderLabels(QStringList{列1文本, 列2文本, ..., 列N文本});

快捷方式:一次性插入多个行的表头

cpp 复制代码
// 语法格式
tableWidget->setRowCount(行数); // 必须先设置行数,即有几行
tableWidget->setVerticalHeaderLabels(QStringList{行1文本, 行2文本, ..., 行N文本});

例如:制作一个基础表格

例如:现在完成"新增一行"、"新增一列"、"删除选中行"、"删除选中列"

(3)QTreeWidget树形控件

使⽤ QTreeWidget 表⽰⼀个树形控件。⾥⾯的每个元素都是⼀个 QTreeWidgetItem 节点,每个 QTreeWidgetItem 可以包含多个⽂本和图标------>文件系统!

对此控件的理解:

链式表格,没层具有列数,比如第0列,第1列,第2列,那么很像电脑的文件夹结构,例如:

根目录是C盘,作为根节点。那么"名称"、"修改日期"、"类型"、"大小"就是每行的列数

如下图:猫、狗作为顶层节点;而家猫属于猫、小菊也属于家猫,它们都属于子节点

cpp 复制代码
┌───────────────┬───────────────┬───────────────┐
│  动物(列0)  │  种类(列1)  │  毛色(列2)  │  ← 3列表头
├───────────────┼───────────────┼───────────────┤
│  猫           │  哺乳动物     │  橘色         │  ← 顶层节点:猫
│  └─ 家猫      │  宠物猫       │  白色         │  ← 子节点:家猫
│      └─ 小菊  │  宠物猫       │  橘白相间     │  ← 孙节点:小菊
│      └─ 小黑  │  宠物猫       │  纯黑         │  ← 孙节点:小黑
├───────────────┼───────────────┼───────────────┤
│  狗           │  哺乳动物     │  黄色         │  ← 顶层节点:狗
└───────────────┴───────────────┴───────────────┘

常用成员函数:

setColumnCount(int col):设置列数

setHeaderLabels(const QString&.......):对应的列名称(单列的话去除 s 即可),例如:

cpp 复制代码
ui->treeWidget->setColumnCount(2);
ui->treeWidget->setHeaderLabels({"名称", "类别"});

QTreeWidgetItem:节点类型

setText(int,const QString&):根据对应的列名称设置具体的内容,例如:

cpp 复制代码
QTreeWidgetItem *cat = new QTreeWidgetItem;

cat->setText(0, "猫");
cat->setText(1, "哺乳动物");

addTopLevelItem(QTreeWidgetItem *):新增节点作为顶层节点

addChild(QTreeWidgetItem *):新增节点作为某个节点的子节点

removeColumn(int):删除对应的整列,然后在重新调用setHeaderLabels设置对应的列名称

cpp 复制代码
// 1. 删除第1列("种类"列)
ui->treeWidget->removeColumn(1);
// 2. 同步更新表头(现在只剩2列)
ui->treeWidget->setHeaderLabels({"动物", "毛色"});

indexOfTopLevelItem(QTreeWidgetItem *):删除对应顶层节点,先获取它的索引

takeTopLevelItem(int):根据索引删除对应的顶层节点

cpp 复制代码
// 1. 找到顶层节点的索引
int index = ui->treeWidget->indexOfTopLevelItem(dog);
// 2. 从树形控件中移除(Qt会自动释放内存)
ui->treeWidget->takeTopLevelItem(index);

indexOfChild(QTreeWidgetItem *):在父节点中找对应子节点的索引

takeChild(int):根据索引删除父节点对应的子节点

cpp 复制代码
//注意:先拿到这个节点的父节点,然后由父节点去找它的索引

// 1. 找到子节点在父节点中的索引
int childIndex = homeCat->indexOfChild(ju);
// 2. 从父节点中移除
delete homeCat->takeChild(childIndex);

currentItem():返回当前选中节点的指针,需要判断是否为空

例如:现在形成一个简易的链式表格

例如:现在我们实现"添加到顶层"、"添加到选中元素"、"删除选中元素"

我们先把树构造出来:

然后完成各功能:

二、容器类控件

(1)GroupBox分组框

使⽤ QGroupBox 实现⼀个带有标题的分组框。可以把其他的控件放到⾥⾯作为⼀组,那么方框里面的元素父类就不是 this 了,而是这个方框:

例如:

(2)TabWidget标签页

使⽤ QTabWidget 实现⼀个带有标签⻚的控件,可以往⾥⾯添加⼀些 widget。进⼀步的就可以通过标签⻚来切换:

常用成员函数:

currentIndex:当前选中的标签页(从0开始计算)

movable:标签页是否可以移动

tabWidget->widget(int):获取到指向这个标签页的指针

addTab(QWidget *page, const QString &label):新增一个标签页(需要new一个QWidget)

removeTab:移除标签页(记得释放内存)

例如:实现新增一个标签页、删除指定标签页

(3)Scroll Area滚动框

作用:把大内容装进一个小容器,由容器自动提供滚动条

QScrollArea:容器类

例如:

(4)Tool Box折叠框

作用:类似文件系统结构,可以展开(如三个页面,每个页面是折叠的,点击展开)

例如:

(5)StackedWidget堆叠框

作用:无标签的堆叠面板,多个页面进行折叠

例如:

(6)Widget与Frame窗口容器

作用:Widget:一个窗口容器,边框透明,而Frame是QWidget的子类,增加了可见边框

三、布局管理器

(1)垂直/水平/网格/表格布局

使⽤ QVBoxLayout 或者 QHBoxLayout 或者 QGridLayout 表⽰布局管理器

帮你美化排版,同时支持嵌套,代码插入节点都是 addWidget 成员函数,同时使用setLayout将布局器增加到当前窗口才能完成显示

注意:QGridLayout和QFormLayout的区别:

GridLayout属于网格布局,需要手动设置行列,需要手动美化排版

FormLayout属于表格布局,自动排版对齐

例如:

(2)表单布局

Qt 还提供了 QFormLayout ,属于是 QGridLayout 的特殊情况,专⻔⽤于实现两列表单的布局:

使用 setLayout 添加到当前窗口,并且使用 **addRow (可变参数)**来按行添加

例如:实现一个用户信息输入的场景

(3)空白间隔

使⽤布局管理器的时候,可能需要在控件之间,添加⼀段空⽩ .就可以使⽤ QSpacerItem 来表⽰,利用布局管理器的成员函数 addSpacerItem 将空白控件增加到指定的位置

常用成员函数:

width:空白的宽度

height:空白的高度

例如:现在有一个垂直布局的管理器,我需要给第一个和第二个按钮之间使用自定义间隔

四、弹簧

作用:在布局中占据"空白",来用于排版,在运行时不可见

例如:

五、QT窗口

QT窗口介绍

理解:QT里可视化元素分为两类(窗口容器和内容控件),现在学的是窗口容器,关系:

cpp 复制代码
QWidget(祖宗)
├── QMainWindow(主窗口容器,带框架)
├── QLabel(内容控件:显示文本)
├── QLineEdit(内容控件:输入文本)
├── QPushButton(内容控件:按钮)
├── QTreeWidget(内容控件:树形)
├── QTabWidget(内容控件:标签页)
└── ...(所有可视化控件都是它的子类)

即窗口容器是继承自 QWidget 的另外一个功能类:专门用来做窗口的!

因此Qt窗口是通过 QMainWindow 类来实现的,继承⾃QWidget类,而 QMainWindow 包含**⼀个菜单栏、⼀个状态栏和⼀个中⼼部件 和 多个⼯具栏、多个浮动窗口**,下面就是分批学习:

六、菜单栏

(1)创建菜单栏

Qt 中的菜单栏是通过 QMenuBar 这个类来实现的,菜单栏中包含菜单。菜单中包含菜单项。

菜单栏创建完成之后,需要通过 setMenuBar 加入到当前窗口

**注意:**上面这种方式是可能存在内存泄漏的,因为只能有一个菜单栏,多次new就会出现泄漏

因此有更加保险的方法,采用 QMenuBar * menu = this -> menuBar ( ) 直接获取菜单栏

(2)创建菜单

每个菜单是通过QMenu这个类来实现,并在构造函数完成描述,之后用addMenu加入菜单栏

(3)创建菜单选项

每个菜单选项是通过QAction这个类来实现,并在构造函数完成描述之后通过addAction加入菜单

(4)设置快捷键

在菜单和菜单选项中可以直接在构造函数的标签描述中增加快捷键,加入 &字母 即可,例如:

只不过需要注意的是,点击信号现在是triggered(),而不是clicked()

(5)举例

例如:创建一个菜单栏,给它增加多个菜单,并且给每个菜单加入多个菜单选项:

(6)子菜单

虽然一个窗口只存在一个菜单栏,但是可以有多个子菜单,一个菜单通过addMenu来填加子菜单

例如:

(7)分割线

可以在相邻菜单选项中添加分割线,直接使用菜单的成员函数addSeparator增加即可:

(8)添加图标

使用 QIcon 可以给菜单选项添加图标,需要注意的是:如果给菜单添加图标,则文字不可显示

七、工具栏

工具栏其实就是菜单选项的快捷方式,由于菜单选项都是在菜单里面的,可能不方便

先创建一个QToolBar工具栏,用addToolBar添加当前窗口,再通过addAction增加菜单选项即可:

(如果想鼠标放在菜单选项中有显示的话,可以使用setToolTip给菜单选项设置提示词)

八、状态栏

状态栏一般在底下显示,比如各种进度条,最保险的方法是通过 this -> statusBar 完成创建

再用 setStatusBar 添加到当前的窗口,然后通过 addWidget 或者 addPermanentWidget 添加控件

可以按如下方式设置为左或者右竖直显示,例如:


例如:在状态栏中添加一个进度条和一个label

九、滑动窗口

在Qt中,浮动窗⼝也称之为铆接部件。浮动窗⼝是通过QDockWidget类来实现浮动的功能。浮动窗⼝⼀般是位于核⼼部件的周围,可以有多个,再通过addDockWidget将滑动窗口添加到当前窗口。**注意:**滑动窗口无法直接添加控件,但是可以添加QWidget,因此需要先把控件放在QWidget,再通过setWidget将QWidget添加到滑动窗口

(同时滑动窗口也可以通过 setWindowTitle 来设置标题)

在将滑动窗口添加到当前的窗口时,需要选择停靠位置:


例如:创建滑动窗口,并且添加一些控件

十、对话框

对话框其实就是你平常点击某个按钮,它出现的新的"提示框",很像一个小的副窗口,在QT中使用QDiallog来表示对话框,如果想实现自定义对话框,当然得新建一个类,继承QDialog才行:

(1)代码创建

先创建一个QDialog窗口,然后是中间的显示内容,设置显示(show()),设置自动释放内存

由于业务逻辑和用户可能多次使用这个对话框,建议封装为另外一个自定义类完成实现:

选择继承基类:QDialog

那么继承之后,需要把QDialog挂到对象树上,所以需要传QWidget类型的this指针,给基类构造

然后我们去实例化这个自定义类,去实现自定义类的的构造函数即可

(2)图形化创建

图形化创建其实和代码创建是类似的,只不过它是自己去生成继承QDialog的自定义类

先创建另外一个 ui 文件,这个是对话框的图形化界面:

然后自己设置自定义的Dialog类即可:

(3)模态与非模态

模态:弹出这个对话框之后,必须要先处理完这个对话框,否则无法进行其它操作,使用exec()

(原理就是一直阻塞在这里,再执行析构,同时 exec() 会有状态选择的返回值)

非模态:弹出这个对话框之后,可以去操作其它的界面,使用 show()显示

(4)QDialog派生对话框
(1)QMessageBox提示框

作用:可以设置选项,比如"OK"、"Concel"。同时可以选择提示类型,比如警告、提示、通知

第一种创建方式:直接new,

通过 setWindowTitle 直接设置对话窗口标题

通过 setText 直接设置对话框内容

通过 setIcon 直接设置图标,可以用系统比如(QMessageBox::Warning)

通过 setStandardButtons 可以直接设置选项比如:

(QMessageBox::Ok | QMessageBox::Save | QMessageBox::Cancel)

(也可以自定义选项,添加到对话框即可,通过信号判断选项)

通过 exec()的返回值可以执行选择的逻辑

例如:

第二种创建方式:直接使用类的静态成员函数创建,更简单(开始就选择图标,一键设置)

例如:

(2)QColorDialog颜色框

作用:直接弹出一个调色板,让用户选择颜色,那么就可以设置当前窗口、按钮的颜色

通过 QColorDialog::getColor(QColor(默认配色),窗口,窗口标题)来一键调用,返回选择的颜色

例如:

(3)QFileDialog文件操作

作用:目前我们只简单学习,通过这两个接口可以直接打开电脑的文件系统

打开文件:QFileDialog::getOpenFileName(this)

保存文件:QFileDialog::getSaveFileName(this)

例如:

(4)QFontDialog字体框

作用:弹出一个字体属性设置框,返回用户选择的字体信息,那么就可以自定义字体属性设置

通过 QFontDialog::getFont(状态填写) 来弹出字体属性设置框,返回字体属性

例如:

(5)QInputDialog条目框

作用:其实就是一个条目输入框,让用户选择

通过 QInputDialog::getItem(this,"窗口内容","窗口标题",items) 完成选择

例如: