目录
1、认识多元素控件
2、QListWidget
2.1 使用QListWidget
3、QTableWidget
3.1 使用QListWidget
4、QTreeWidget
4.1 使用QTreeWidget
5、QGroupBox
5.1 使用QGroupBox
6、QTabWidget
6.1 使用QTabWidget
结语
前言:
在Qt中,控件之间若是以复合的形式存在界面上,称之为多元素控件。相反,控件之间若是以彼此的形式存在界面上,称之为单元素控件,换句话说,多元素控件中可以存放其他控件。相比于单元素控件,多元素控件提供了丰富的界面显示以提高用户的体验度,还拓宽了开发者对复杂界面设计的范围,可以让界面提供更多的功能,让代码更具封装性。
1、认识多元素控件
Qt中提供的多元素控件有:1、QListWidget QListView,2、QTableWidget QTableView,3、QTreeWidget QTreeView,分别对应列表控件、表格控件、树型控件。可以发现每种类型的控件有两个:后缀一个是Widget,一个是View,就拿QTableWidget和QTableView来说,他们的潜在区别是:
· 使用QTableView时需要创建⼀个Model对象,往QTableView里添加控件实际上是往Model中添加控件,只不过也可以在QTableView中显示出添加的内容。
· 而使用QTableWidget则不需要创建Model对象就可以往QTableWidge添加控件,因为QTableWidget是QTableView的子类,系统已经在QTableWidget中帮我们封装了Model,所以我们直接用即可。
因此本文主要介绍后缀为Widge的多元素控件。
2、QListWidget
QListWidget是一个纵向列表控件,他的逻辑和下拉框QComboBox有点像,都具有选中功能。只不过QListWidget里面保存的是QListWidgetItem类型(是一个控件),而QComboBox里保存只是QString类型。QListWidget控件示意图如下:
QListWidget重要属性介绍如下:
currentRow
|
当前被选中的是第⼏⾏
|
count
|
⼀共有多少⾏
|
sortingEnabled
|
是否允许排序
|
isWrapping
|
是否允许换⾏
|
itemAlignment
|
条目的对⻬⽅式
|
selectRectVisible
|
被选中的元素矩形是否可⻅
|
spacing
|
条目之间的间隔
|
QListWidget常用的接口如下:
addItem(const QString& label)
addItem(QListWidgetItem *
item)
|
给列表中添加条目,可以是QString的方式也可以是QListWidgetItem 的方式
|
currentItem()
|
返回 QListWidgetItem* 表⽰当前选中的条目
|
currentRow() | 返回row,表示获取当前行 |
setCurrentItem(QListWidgetItem* item)
|
选中条目为item的条目
|
setCurrentRow(int row)
| 选中第row行的条目 |
insertItem(const QString& label, int row)
insertItem(QListWidgetItem *
item, int
row)
|
在指定的行数插⼊对应条目
|
item(int row)
|
拿到第row行的条目
|
takeItem(int row)
|
删除指定⾏的条目
|
由于QListWidget的条目是QListWidgetItem控件,作为一个控件,QListWidgetIte自身也提供了相关接口,如下:
setFont
|
设置字体
|
setIcon
|
设置图标
|
setHidden
|
设置隐藏
|
setSizeHint
|
设置尺⼨
|
setSelected
|
设置是否选中
|
setText
| 设置文本 |
setTextAlignment
| 设置文本对齐方式 |
QListWidget的核心信号如下:
currentItemChanged(QListWidgetItem* current, QListWidgetItem* old)
|
选中不同条目时会触发,参数是当前选中的条目和之前选中的条目
|
currentRowChanged(int)
|
选中不同元素时会触发,参数是当前选中元素的⾏数
|
itemClicked(QListWidgetItem* item)
|
点击某个元素时触发
|
itemDoubleClicked(QListWidgetItem* item)
|
双击某个元素时触发
|
itemEntered(QListWidgetItem* item)
|
⿏标进⼊元素时触发
|
2.1 使用QListWidget
实现一个可以通过按钮的方式从而对QListWidget进行条目的增加和删除。界面设计如下:
在widget.cpp文件下写出代码,代码如下:
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
QString tmp = ui->lineEdit->text();//获取到输入框中的文本
if(tmp!="")//若不为空则进行添加
{
//用QListWidgetItem的方式进行添加,用QString也可以添加
QListWidgetItem* q = new QListWidgetItem(tmp);
ui->listWidget->addItem(q);
ui->lineEdit->setText("");
}
}
void Widget::on_pushButton_2_clicked()
{
int row = ui->listWidget->currentRow();//获取当前行
ui->listWidget->takeItem(row);//删除row行的条目
}
测试添加:
测试删除:
3、QTableWidget
QTableWidget表示表格控件,因此他可以有若干行和若干列,表格中的每个单元格就是一个QTableWidgetItem(控件)对象,可以通过ui文件双击QTableWidget控件快速的生成一个框架,效果图如下:
QTableWidget重要属性介绍:
rowCount | 表格行数 |
columCount | 表格列数 |
horizontalHeaderVisible
| 是否显示列的属性信息 |
verticalHeaderVisible
| 是否显示行的属性信息 |
QTableWidget常用接口:
item(int row, int column)
|
根据⾏数列数获取指定的
QTableWidgetItem*
|
setItem(int row, int column, QTableWidgetItem*)
|
根据⾏数列数设置表格中的元素
|
currentItem()
|
返回当前选中的元素 QTableWidgetItem*
|
currentRow()
| 返回当前选中的元素的行数 |
currentColumn()
| 返回当前选中的元素的列数 |
row(QTableWidgetItem* )
|
获取指定 item 是第几行
|
column(QTableWidgetItem* )
|
获取指定 item 是第⼏列
|
rowCount()
| 获取⾏数 |
columnCount()
|
获取列数
|
insertColumn(int column)
|
在第 column 列插⼊新列
|
insertRow(int row)
|
在第 row ⾏处插⼊新⾏
|
removeRow(int row)
|
删除第 row ⾏
|
removeColumn(int column)
|
删除第 column 列
|
setHorizontalHeaderItem(int
column, QTableWidgetItem*)
|
设置指定列的表头
|
setVerticalHeaderItem(int row,
QTableWidgetItem*)
|
设置指定⾏的表头
|
和QListWidget一样,QTableWidget里的控件QTableWidgetItem也提供了对应的接口,这些接口和QListWidget基本一致,所以不再一一介绍了。
QTableWidget核心信号:
cellClicked(int row, int column)
|
点击单元格时触发
|
cellDoubleClicked(int row, int column)
|
双击单元格时触发
|
cellEntered(int row, int column)
|
⿏标进⼊单元格时触发
|
currentCellChanged(int row, int
column, int previousRow, int previousColumn)
|
选中不同单元格时触发
|
3.1 使用QListWidget
在界面上创建一个QListWidget,再创建四个按钮和一个输入框,四个按钮分别是:新增一行、新增一列、删除选中行、删除选中列。可以通过按钮对QListWidget表格进行修改,而输入框里的文本就会作为新增一列的表头。界面设计如下:
代码实现:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->lineEdit->setPlaceholderText("请输入新增列的表头");
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_addcolumn_clicked()//添加列
{
int column = ui->tableWidget->columnCount();
ui->tableWidget->insertColumn(column);
QString tmp = ui->lineEdit->text();
if(tmp!="")
{
ui->tableWidget->setHorizontalHeaderItem(column,new QTableWidgetItem(tmp));
}
}
void Widget::on_pushButton_addrow_clicked()//添加行
{
int row = ui->tableWidget->rowCount();
ui->tableWidget->insertRow(row);
}
void Widget::on_pushButton_delcolumn_clicked()//删除列
{
int column = ui->tableWidget->currentColumn();
ui->tableWidget->removeColumn(column);
}
void Widget::on_pushButton_delrow_clicked()//删除行
{
int row = ui->tableWidget->currentRow();
ui->tableWidget->removeRow(row);
}
运行结果(部分测试截图):
4、QTreeWidget
QTreeWidget是树型控件,里面的每一个元素是QTreeWidgetItem,和上述两个多元素控件不同的是,树型控件里的QTreeWidgetItem可以继续嵌套QTreeWidgetItem,就如同将QTreeWidgetItem看成结点,该结点下可以有多个子结点。QTreeWidget效果图如下:
上图中的1是该树的第二层结点,并不是根结点,我们只能从根结点的下一层结点开始设计,可以在ui文件中添加多个与1同级的结点,概念图如下:
一般将1所在层级的下一层级的结点叫做顶层结点。
QTreeWidget常用接口(以整个控件的视角来看):
clear
|
清空所有⼦节点
|
addTopLevelItem(QTreeWidgetItem* item)
|
新增顶层节点
|
topLevelItem(int index)
|
获取指定下标的顶层节点
|
topLevelItemCount()
|
获取顶层节点个数
|
indexOfTopLevelItem(QTreeWidgetItem* item)
|
查询指定节点是顶层节点中的下标
|
takeTopLevelItem(int index)
|
删除指定的顶层节点,返回 QTreeWidgetItem* 表示被删除的元素
|
currentItem()
|
获取到当前选中的节点, 返回 QTreeWidgetItem*
|
setCurrentItem(QTreeWidgetItem* item)
|
选中指定节点
|
setExpanded(bool)
|
展开/关闭节点
|
setHeaderLabel(const QString& text)
|
设置 TreeWidget 的 header 名称
|
QTreeWidget核心信号:
currentItemChanged(QTreeWidgetItem*
current, QTreeWidgetItem* old)
|
切换选中元素时触发
|
itemClicked(QTreeWidgetItem* item, int col)
|
点击元素时触发
|
itemDoubleClicked(QTreeWidgetItem* item, int col)
|
双击元素时触发
|
itemEntered(QTreeWidgetItem* item, int col)
|
⿏标进⼊时触发
|
itemExpanded(QTreeWidgetItem* item)
|
元素被展开时触发
|
itemCollapsend(QTreeWidgetItem* item)
|
元素被折叠时触发
|
QTreeWidgetItem常用接口(以结点的视角来看):
addChild(QTreeWidgetItem* child)
|
新增⼦结点
|
childCount()
|
⼦结点的个数
|
child(int index)
|
获取指定下标的⼦结点. 返回 QTreeWidgetItem*
|
takeChild(int index)
|
删除对应下标的⼦结点
|
removeChild(QTreeWidgetItem* child)
|
删除对应的⼦结点
|
parent()
|
获取该元素的⽗结点
|
4.1 使用QTreeWidget
创建一个QTreeWidget和三个按钮以及一个输入框,三个按钮分别是:添加到顶层元素、添加到选中元素、删除选中元素。输入框中的文本作为元素的名称。界面设计如下:
代码实现:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->lineEdit->setPlaceholderText("请输入元素名称");
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()//添加到顶层元素
{
QString tmp = ui->lineEdit->text();
if(tmp!="")
{
QTreeWidgetItem* q = new QTreeWidgetItem();
q->setText(0,tmp);
ui->treeWidget->addTopLevelItem(q);
}
}
void Widget::on_pushButton_2_clicked()//添加到选中元素
{
QString tmp = ui->lineEdit->text();
QTreeWidgetItem* cur = ui->treeWidget->currentItem();
if(cur&&tmp!="")//要判断当前是否有选中,没有选中则不进行添加
{
QTreeWidgetItem* q = new QTreeWidgetItem();
q->setText(0,tmp);
cur->addChild(q);
cur->setExpanded(true);//添加完成后自动展开
}
}
void Widget::on_pushButton_3_clicked()//删除选中元素
{
QTreeWidgetItem* del = ui->treeWidget->currentItem();
if(del)
{
QTreeWidgetItem* parent = del->parent();
if(parent==nullptr)//要删除的结点为顶层结点,那么交给treeWidget处理
{
int index = ui->treeWidget->indexOfTopLevelItem(del);
ui->treeWidget->takeTopLevelItem(index);
}
else//要删除的结点为子结点,那么交给parent处理即可
{
parent->removeChild(del);
}
}
}
运行结果(部分截图):
5、QGroupBox
QGroupBox并不是一个真正意义上的多元素控件,他是一个带有标题的分组框,框内可以收纳多个控件,因此他属于容器类控件,不过他的逻辑和多元素控件相似,即控件内可以存放其他控件。QGroupBox的目的就是让控件分组更加明显,QGroupBox效果图如下:
此时框中控件的父元素不再是this指针,而是QGroupBox。
QGroupBox核心属性:
title
|
分组框的标题
|
alignment
|
分组框内部内容的对⻬⽅式
|
flat
|
是否是 "扁平" 模式
|
checkable
|
是否可选择,设为 true,则在 title 前⽅会多出⼀个可勾选的部分
|
checked
|
描述分组框的选择状态 (前提是 checkable 为 true)
|
5.1 使用QGroupBox
QGroupBox的使用相对简单,仅仅只是美化界面的作用,比如将界面上的功能进行模块化,例子如下:
代码实现:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//汉堡框
ui->comboBox->addItem("香辣鸡腿堡");
ui->comboBox->addItem("新奥尔良鸡腿堡");
//饮料框
ui->comboBox_2->addItem("可乐");
ui->comboBox_2->addItem("雪碧");
}
Widget::~Widget()
{
delete ui;
}
运行结果:
6、QTabWidget
QTabWidget是一个带标签页的容器类控件,他和QGroupBox一样,也可以收纳多个控件并达到分组的效果,不过QTabWidget是以切换标签页来进行分组的,每个标签页就如同一个小窗口。其效果图如下:
QTabWidget属性介绍:
tabPosition
|
标签⻚所在的位置-上方、下方、左边、右边
|
currentIndex
|
当前选中了第⼏个标签⻚ (从 0 开始计算)
|
currentTabText
|
当前选中的标签⻚的⽂本(文本给用户看的)
|
currentTabName
|
当前选中的标签⻚的名字(名字给程序看的)
|
currentTabIcon
|
当前选中的标签⻚的图标
|
currentTabToolTip
|
当前选中的标签⻚的提示信息
|
tabsCloseable
|
标签⻚是否可以关闭
|
movable
|
标签⻚是否可以移动
|
QTabWidget常用接口:
count()
|
获取到标签⻚的个数
|
addTab(QWidget*,const QString&)
|
新增标签⻚,所谓标签页实际上就是QWidget控件
|
removeTab
|
删除标签⻚
|
currentIndex
|
获取到当前标签⻚的下标
|
setCurrentIndex
|
切换当前标签⻚
|
QTabWidget核心信号:
currentChanged(int)
|
在标签⻚发⽣切换时触发,参数为被点击的选项卡编号
|
tabBarClicked(int)
|
在点击选项卡的标签条的时候触发,参数为被点击的选项卡编号
|
tabBarDoubleClicked(int)
|
在双击选项卡的标签条的时候触发,参数为被点击的选项卡编号
|
tabCloseRequest(int)
|
在标签⻚关闭时触发. 参数为被关闭的选项卡编号
|
6.1 使用QTabWidget
创建一个QTabWidget和两个按钮,分别是:新增标签页、删除当前页。通过这两个按钮来控制QTabWidget的标签页,并且创建一个标签页后自动给该页设置文本, 以及在该页中创建一个label标签。界面设计如下:
代码实现:
#include "widget.h"
#include "ui_widget.h"
#include <QLabel>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
int cnt = ui->tabWidget->count();
QWidget* qw = new QWidget(this);
ui->tabWidget->addTab(qw,"标签页"+QString::number(cnt+1));
//给当前标签添加label控件
QLabel* ql = new QLabel(qw);//注意这里挂的是qw而不是this指针
ql->setText("标签页"+QString::number(cnt+1));
ql->move(50,50);
//新增完成后,自动切换到新增的标签页上
ui->tabWidget->setCurrentWidget(qw);
}
void Widget::on_pushButton_2_clicked()
{
int index = ui->tabWidget->currentIndex();
ui->tabWidget->removeTab(index);
}
运行结果:
结语
以上就是关于多元素控件的讲解,多元素控件的表现形式更为丰富,他的核心主要在于外部框架的使用以及对内部控件的理解,这也使得多元素控件的各种接口繁多,要区分哪些接口是作用于外部框架的,而哪些接口是作用于内部控件的,对于属性也是如此。