Qt开发——常用控件(多元素控件&&容器类控件)
Qt提供的多元素控件有:
列表相关
QListWidget
QListView
表相关
QTableWidget
QTableView
树相关
QTreeWidget
QTreeView
xxWidget和xxView的区别。
xxView是更偏向底层的实现。
xxWidget是基于xxView封装而来的
此处的xxView 是 MVC结构 的一种典型实现,MVC也是软件开发中,非常经典的软件结构的组织形式了。
M model 数据
V view 视图(界面)
C controller 控制器——数据和视图之间的业务流程
此处 xxView只是负责实现了视图,不负责数据如何存储表示,更不负责数据和视图之间的交互。因此如果使用xxView,那么就需要自己实现model和controller的部分。
xxWidget基于 xxView 同时把model和controller都帮我们实现好了,拿过来就可以直接使用,还提供了功能很方便的api
List Widget
使用QListWidget能够显示一个纵向的列表

QListWidget属性
currentRow:当前被选中的是第几行
count:一共有多少行
sortingEnabled:是否允许排序
isWrapping:是否允许换行
itemAlignment:元素的对齐方式
selectRectVisible:被选中的元素矩形是否可见(上图显示的蓝色高亮)
spacing:元素之间的间隔
核心方法
addItem(const QString& label)
addItem(QListWidgetItem *item)
这两个都是添加列表中的元素(上图所示的一行),哪为什么会有两个呢
列表中的 每个元素/每一项 就称为一个 Item,更具体的说,就是通过 QListWidgetItem 类表示的。提供两个函数,那么我们既可以直接传QString,也可以传上边类的指针
currentItem():返回 QListWidgetItem * 表示当前选中的元素
setCurrentItem(QListWidgetItem* item) :设置选择哪个元素
setCurrentRow(int row):设置选中第几行的元素
insertItem(const QString& label,int row)
insertItem(QListWidgetItem *item,int row)
在指定位置插入元素
item(int row):返回 QListWidgetItem * 表示第row行的元素
takeItem(int row):删除指定行的元素,返回 QListWidgetItem *表示哪个元素被删除了
核心信号
currentItemChanged(QListWidgetItem*current,QListWidgetItem* old)
选中不同元素时会触发。参数是当前选中的元素和之前选中的元素
currentRowChanged(int)
选中不同元素时会触发。参数是当前选中元素的行数
itemClicked(QListWidgetItem* item)
点击某个元素时触发
itemDoubleClicked(QListWidgetItem* item)
双击某个元素时触发
itemEntered(QListWidgetItem* item)
鼠标进入元素时触发
QListWidgetItem
之前提到了QListWidgetItem这个类这个类表示 QListWidget 中的一个元素
核心方法如下,本质上就是一个"文本+图标"构成的
setFont:设置字体
setIcon:设置图标
setHidden:设置隐藏
setSizeHint:设置尺寸
setSelected:设置是否选中
setText:设置文本
setTextAlignment:设置文本对齐方式
QListWidget 的使用
用ListWidget实现对一个列表的增添的删除
在设计页面先拖拽一个listwidget过来

如果拖拽成listview也没事,可以直接右键变型为listwidget

再新增一个lineedit和两个按钮,lineedit用来输入元素,按钮用来增添和删除

在构造函数中为listwidget添加元素
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->listWidget->addItem("abcdef");
ui->listWidget->addItem(new QListWidgetItem("123456"));
ui->listWidget->addItem("zxcvbnnm");
}

也可以直接右键ListWidget,选中编辑项目,然后直接新增/删除元素

完成两个按钮的slot函数
void Widget::on_pushButton_push_clicked()
{
//获取label中的内容
const QString& text = ui->lineEdit->text();
//把获取到的内容插入到ListWidget中
ui->listWidget->addItem(text);
}
void Widget::on_pushButton_delete_clicked()
{
//先获取被选中的元素是哪个
int row = ui->listWidget->currentRow();
if(row < 0)
{
return;
}
ui->listWidget->takeItem(row);
}

再试试信号currentItemChanged
void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
if(current != nullptr)
{
qDebug()<<"当前选中的元素是:"<<current->text();
}
if(previous != nullptr)
{
qDebug()<<"上一个选中的元素是:"<<previous->text();
}
}

Table Widget
使用QTableWidget表示一个表格的控件。一个表格中包含若干行,每行中包含若干列。
表格中的每个单元格,都表示一个 QTableWidgetItem 对象
QTableWidget方法
QTableWidget的核心方法
item(int row,int column):根据行数列数获取指定的QTableWidgetItem*
setItem(int row,int column,QTableWidget*)
根据行数列数设置表格中的元素
currentItem():返回被选中的元素QTableWidgetItem*
currentRow():返回被选中的元素是第几行
currentColumn():返回被选中的元素是第几列
row(QTableWidgetItem*):获取指定Item是第几行
column(QTableWidgetItem* ):获取指定Item是第几列
rowCount():获取行数
columnCount()获取列数
insertRow(int row)在第row行处插入新行
insertColumn(int column) 在第column列插入新列
removeRow(int row):删除第row行
removeColumn(int column):删除第column列
setHorizontalHeaderItem(int column,QTableWidget*):设置指定列的表头
setVerticalHeaderItem(int row,QTableWidget* ):设置指定行的表头
QTableWidgetItem
QTableWidgetItem单元格的核心信号
cellClicked(int row,int column):
点击单元格时触发
cellDoubleClicked(int row,int column):
双击单元格时触发
cellEntered(int row,int column):
鼠标进入单元格时触发
currentCellChanged(int row,int column,int previousRow,int previousColumn):
选中不同单元格时触发
QTableWidgetItem核心方法
row():获取当前是第几行
column():获取当前是第几列
setText(const QString&):设置文本
setTextAlignment(int):设置文本对齐
setIcon(const QIcon&): 设置图标
setSelected(bool): 设置被选中
setSizeHints(const QSize&): 设置尺寸
setFont(const QFont&) :设置字体
QTableWidget的使用
在界面上创建QTableWidget 和4个按钮,一个输入框

编写widget.cpp构造函数,构造表格中的初始数据(也可以通过图形化界面操作:右键编辑项目——新增行、列。如果当前表格的数据是固定的,那么就可以通过图形化界面编辑,但是实际开发中很多时候数据是由文件、网络来加载的,此时通过图形化编辑就不合适了)
创建3行
//创建3行
ui->tableWidget->insertRow(0);
ui->tableWidget->insertRow(1);
ui->tableWidget->insertRow(2);
创建3列
//创建3列
ui->tableWidget->insertColumn(0);
ui->tableWidget->insertColumn(1);
ui->tableWidget->insertColumn(2);
设置列名
ui->tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("学号"));
ui->tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("姓名"));
ui->tableWidget->setHorizontalHeaderItem(2,new QTableWidgetItem("年龄"));
设置初始数据
注意是先行后列

//给表格中添加数据
ui->tableWidget->setItem(0,0,new QTableWidgetItem("20250101"));
ui->tableWidget->setItem(0,1,new QTableWidgetItem("张三"));
ui->tableWidget->setItem(0,2,new QTableWidgetItem("21"));
ui->tableWidget->setItem(1,0,new QTableWidgetItem("20250102"));
ui->tableWidget->setItem(1,1,new QTableWidgetItem("李四"));
ui->tableWidget->setItem(1,2,new QTableWidgetItem("23"));
ui->tableWidget->setItem(2,0,new QTableWidgetItem("20250103"));
ui->tableWidget->setItem(2,1,new QTableWidgetItem("王五"));
ui->tableWidget->setItem(2,2,new QTableWidgetItem("20"));
运行完是这样的

还有4个按钮的slot函数没有完成
void Widget::on_pushButton_insertrow_clicked()
{
//需要知道当前有多少行(然后再插入新行)
int row_count = ui->tableWidget->rowCount();
ui->tableWidget->insertRow(row_count);
}
void Widget::on_pushButton_insertcolumn_clicked()
{
//需要知道当前有多少列
int Column_count = ui->tableWidget->columnCount();
ui->tableWidget->insertColumn(Column_count);
//设置列名(从lineEdit获取)
const QString& text = ui->lineEdit->text();
ui->tableWidget->setHorizontalHeaderItem(Column_count,new QTableWidgetItem(text));
}
void Widget::on_pushButton_deleterow_clicked()
{
//获取当前选中行
int curRow = ui->tableWidget->currentRow();
//删除选中行
ui->tableWidget->removeRow(curRow);
}
void Widget::on_pushButton_deletecolumn_clicked()
{
//获取当前选中列
int curColumn = ui->tableWidget->currentColumn();
//删除
ui->tableWidget->removeColumn(curColumn);
}
代码
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建3行
ui->tableWidget->insertRow(0);
ui->tableWidget->insertRow(1);
ui->tableWidget->insertRow(2);
//创建3列
ui->tableWidget->insertColumn(0);
ui->tableWidget->insertColumn(1);
ui->tableWidget->insertColumn(2);
//给3个列创建列名(水平方向表头)
ui->tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("学号"));
ui->tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("姓名"));
ui->tableWidget->setHorizontalHeaderItem(2,new QTableWidgetItem("年龄"));
//给表格中添加数据
ui->tableWidget->setItem(0,0,new QTableWidgetItem("20250101"));
ui->tableWidget->setItem(0,1,new QTableWidgetItem("张三"));
ui->tableWidget->setItem(0,2,new QTableWidgetItem("21"));
ui->tableWidget->setItem(1,0,new QTableWidgetItem("20250102"));
ui->tableWidget->setItem(1,1,new QTableWidgetItem("李四"));
ui->tableWidget->setItem(1,2,new QTableWidgetItem("23"));
ui->tableWidget->setItem(2,0,new QTableWidgetItem("20250103"));
ui->tableWidget->setItem(2,1,new QTableWidgetItem("王五"));
ui->tableWidget->setItem(2,2,new QTableWidgetItem("20"));
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_insertrow_clicked()
{
//需要知道当前有多少行(然后再插入新行)
int row_count = ui->tableWidget->rowCount();
ui->tableWidget->insertRow(row_count);
}
void Widget::on_pushButton_insertcolumn_clicked()
{
//需要知道当前有多少列
int Column_count = ui->tableWidget->columnCount();
ui->tableWidget->insertColumn(Column_count);
//设置列名(从lineEdit获取)
const QString& text = ui->lineEdit->text();
ui->tableWidget->setHorizontalHeaderItem(Column_count,new QTableWidgetItem(text));
}
void Widget::on_pushButton_deleterow_clicked()
{
//获取当前选中行
int curRow = ui->tableWidget->currentRow();
//删除选中行
ui->tableWidget->removeRow(curRow);
}
void Widget::on_pushButton_deletecolumn_clicked()
{
//获取当前选中列
int curColumn = ui->tableWidget->currentColumn();
//删除
ui->tableWidget->removeColumn(curColumn);
}

Tree Widget
使用QTreeWidget 表示一个树形控件。里边的每个元素,都是⼀个QTreeWidgetItem ,每个 QTreeWidgetItem 可以包含多个文本和图标,每个文本/图标为一个列。
可以给QTreeWidget 设置顶层节点(顶层节点可以有多个,也就是此树形结构异于其他树形结构——没有根节点,从根节点下一层节点(顶层节点)开始),然后再给顶层节点添加子节点,从而构成树形结构。
QTreeWidget属性
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,intcol)
点击元素时触发
itemDoubleClicked(QTreeWidgetItem* item, int col)
双击元素时触发
itemEntered(QTreeWidgetItem* item,int col)
鼠标进入时触发
itemExpanded(QTreeWidgetItem* item)
元素被展开时触发
itemCollapsend(QTreeWidgetItem* item)
元素被折叠时触发
上边都是关于顶层节点的那么如何进行子节点的创建呢?
QTreeWidgetItem
QTreeWidgetItem就是子节点相关
核心属性
text 持有的文本
textAlignment 文本本对齐方式
icon 持有的图表
font 文本本字体
hidden 是否隐藏
disabled 是否禁⽤
expand 是否展开
sizeHint 尺寸大小
selected 是否选中
QTreeWidgetItem 核心方法
addChild(QTreeWidgetItem*child) 新增子节点
childCount() 子节点的个数
child(int index) 获取指定下标的子节点。返回QTreeWidgetItem*
takeChild(int index) 删除对应下标的子节点
removeChild(QTreeWidgetItem* child)
删除对应的子节点 parent(), 获取该元素的父节点
QTreeWidget的使用
界面创建一个QTreeWidget和一个lineEdit以及3个pushButton按钮。

初始化QTreeWidget,可以在界面中直接操作,依旧是右键,编辑项目
左下角三个按钮分别是:新建项目,新建子项目,删除项目

还可以在构造函数中进行初始化
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//设置根节点的名字
ui->treeWidget->setHeaderLabel("动物");
//新增顶层节点
QTreeWidgetItem* item1 = new QTreeWidgetItem();
item1->setText(0,"猫");//每个节点都可以设置多列,只不过我这里只设置了一列
ui->treeWidget->addTopLevelItem(item1);
//顶层节点
QTreeWidgetItem* item2 = new QTreeWidgetItem();
item2->setText(0,"狗");
ui->treeWidget->addTopLevelItem(item2);
//顶层节点
QTreeWidgetItem* item3 = new QTreeWidgetItem();
item3->setText(0,"鸟");
ui->treeWidget->addTopLevelItem(item3);
//猫的子节点
QTreeWidgetItem* item1c1 = new QTreeWidgetItem();
QTreeWidgetItem* item1c2 = new QTreeWidgetItem();
QTreeWidgetItem* item1c3 = new QTreeWidgetItem();
item1c1->setText(0,"橘猫");
item1c2->setText(0,"狸花猫");
item1c3->setText(0,"布偶猫");
item1->addChild(item1c1);
item1->addChild(item1c2);
item1->addChild(item1c3);
//狗的子节点
QTreeWidgetItem* item2c1 = new QTreeWidgetItem();
QTreeWidgetItem* item2c2 = new QTreeWidgetItem();
item2c1->setText(0,"中华田园犬");
item2c2->setText(0,"哈士奇");
item2->addChild(item2c1);
item2->addChild(item2c2);
}
然后就是完成我们的三个按钮的槽函数
//添加顶层元素slot函数
void Widget::on_pushButton_insertTopLevelItem_clicked()
{
//获取输入框的内容
const QString& text = ui->lineEdit->text();
//构造一个Item
QTreeWidgetItem* item = new QTreeWidgetItem();
item->setText(0,text);//把输入框的内容录入item
ui->treeWidget->addTopLevelItem(item);//添加到顶层节点
}
//添加到选中元素的slot函数
void Widget::on_pushButton_insertItem_clicked()
{
//获取当前选中的元素
QTreeWidgetItem* itemf = ui->treeWidget->currentItem();
if(itemf == nullptr)
{
return;
}
//获取输入框的内容(新增节点的名字)
const QString& text = ui->lineEdit->text();
//构造一个 item
QTreeWidgetItem* itemc = new QTreeWidgetItem();
itemc->setText(0,text);
//把新增元素添加到当前选中元素中
itemf->addChild(itemc);
}
void Widget::on_pushButton_deleteItem_clicked()
{
//获取当前选中的元素
QTreeWidgetItem* itemcurr = ui->treeWidget->currentItem();
if(itemcurr == nullptr)
{
return;
}
//获取当前节点的父节点,如果父节点是空,那么就要调用顶层节点的函数删除(不是的话就用父节点来删除当前节点)
QTreeWidgetItem* parent = itemcurr->parent();
if(parent == nullptr)
{
//获取顶层节点(被选中的节点)的下标
int index = ui->treeWidget->indexOfTopLevelItem(itemcurr);
//删除节点
ui->treeWidget->takeTopLevelItem(index);
}
else
{
//调用父节点删除对应的子节点
parent->removeChild(itemcurr);
}
}
注意:上述这几个控件相关的操作,数据都是在内存中保存的,无论在界面上进行任何操作,重新运行程序之后,之前的数据就都没了
如果要想让数据能够重启程序还不丢失,那么就需要编写更多的代码把内存中的数据获取到,写入到文件中,并且在程序下一次运行的时候从文件中加载数据
容器类控件
Group Box
使用QGroupBox 实现⼀个带有标题的分组框。可以把其他的控件放到里边作为一组。
注意:
多元素控件,包含的内容是一个一个自定义好的"Item"对象。
容器类控件,包含的内容是前面所学的各种控件放一块
不要把QGroupBox 和 QButtonGroup 混淆

属性
title:分组框的标题
alignment:分组框内部内容的对齐方式
flat: 是否是"扁平"模式
checkable:是否可选择。设为true,则在title前边会多出一个个可勾选的部分。
checked: 描述分组框的选择状态(前提是checkable为true)
使用
给麦当劳案例加上分组框
在界面上拖拽所需控件

总共3组

把flat和checkable勾上看看

Tab Widget
使用 QTabWidget 实现一个带有标签页的控件,可以往里边添加一些widget。进一步的就可以通过标签页来切换。
属性
tabPosition 标签页所在的位置
North 上方
South 下方
West 左侧
East 右侧
currentIndex: 当前选中了第几个标签页(从0开始计算)
currentTabText: 当前选中的标签页的文本
currentTabName: 当前选中的标签页的名字
currentTabIcon:当前选中的标签页的图标
currentTabToolTip: 当前选中的标签页的提示信息
tabsCloseable: 标签页是否可以关闭
movable:标签页是否可以移动
核心信号
currentChanged(int):
在标签页发生切换时触发,参数为被点击的选项卡编号
tabBarClicked(int):
在点击选项卡的标签条的时候触发。参数为被点击的选项卡编号
tabBarDoubleClicked(int)
在双击选项卡的标签条的时候触发。参数为被点击的选项卡编号
tabCloseRequest(int):
在标签页关闭时触发。参数为被关闭的选项卡编号
使用
拖拽TabWidget控件

运行后是这样的,可以点击tab1,tab2选项卡进行切换标签页

可以将一些控件放入标签页中,右下角有属性可以更改标签页名称

右键控件还可以进行页的插入和删除,其中3的页3选项中有子选项可以进行删除

Tab Widget的使用
使用标签页管理多组控件
在界面上创建一个QTabWidget ,和两个按钮

编写widget.cpp进行初始化,给标签页中放个简单的label
注意:
新创建的label的父元素,是ui->tab 和 ui->tab_2 。
Qt中使用父子关系决定该控件 "在哪里"
#include "widget.h"
#include "ui_widget.h"
#include <QLabel>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//在每个标签页中添加一个label
QLabel* label1 = new QLabel(ui->tab);
label1->setText("标签页1");
label1->resize(100,50);
QLabel* label2 = new QLabel(ui->tab_2);
label2->setText("标签页2");
label2->resize(100,50);
}
Widget::~Widget()
{
delete ui;
}
实现两个按钮的槽函数以及标签页信号的使用
void Widget::on_pushButton_clicked()
{
//使用adTab 方法来创建新的标签页——参数1要指定一个Qwidget
//参数2 指定标签页的标题
int count = ui->tabWidget->count();//获取标签页的数量
QWidget* w = new QWidget();
ui->tabWidget->addTab(w,QString("Tab")+QString::number(count + 1));
//添加QLabel显示内容
QLabel* label = new QLabel(w);
label->setText(QString("标签页")+QString::number(count + 1));
label->resize(100,50);
//新增标签页之后自动选中
ui->tabWidget->setCurrentIndex(count);
}
void Widget::on_pushButton_2_clicked()
{
//获取选中标签页的下标
int index = ui->tabWidget->currentIndex();
//删除操作
ui->tabWidget->removeTab(index);
}
void Widget::on_tabWidget_currentChanged(int index)
{
qDebug()<<"当前选中的标签页下标是"<<index;
}
更多推荐
所有评论(0)