Qt-常用控件(3)-多元素控件、容器类控件和布局管理器

1. 多元素控件

Qt 中提供的多元素控件有:

  • QListWidget

  • QListView

  • QTableWidget

  • QTableView

  • QTreeWidget

  • QTreeView
    xxWidget 和 xxView 之间的区别,以 QTableWidget 和 QTableView 为例.

  • QTableView 是基于 MVC 设计的控件 .QTableView 自身不持有数据,使用 QTableView 的时候需要用户创建一个 Model对象(比如 QStandardModel),并且把 Model和QTableView 关联起来.后续修改 Model 中的数据就会影响 QTableView 的显示; 修改QTableView 的显示也会影响到 Model 中的数据(双向绑定).

  • QTableWidget 则是 QTableView 的子类,对 Model进行了封装.不需要用户手动创建Model对象,直接就可以往 QTableWidget 中添加数据了.

1.1 QListWidget

使用 QListwidget 能够显示一个纵向的列表 ,就相当于一个列表形如:

核⼼属性

属性 说明
currentRow 当前被选中的是第几行
count 一共有多少行
sortingEnabled 是否允许排序
isWrapping 是否允许换行
itemAlignment 元素的对齐方式
selectRectVisible 被选中的元素矩形是否可见
spacing 元素之间的间隔

核心方法

方法 说明
addltem(const QString& label) addltem(QListWidgetltem*item) 列表中添加元素.
currentltem() 返回 QListWidgetltem*表示当前选中的元素
setCurrentltem(OListWidgetltem*item) 设置选中哪个元素
setCurrentRow(int row) 设置选中第几行的元素
insertltem(const QString& label, int row) insertltem(QListWidgetltem *item, int row) 在指定的位置插入元素
item(int row) 返回 QListWidgetltem*表示第 row 行的元素
takeltem(int row) 删除指定行的元素,返回 QListWidgetltem* 表示是哪个元素被删除了

核心信号

方法 说明
currentltemChanged(QListWidgetltemcurrent,QListWidgetltem old) 选中不同元素时会触发.参数是当前选中的元素和之前选中的元素:
currentRowChanged(int) 选中不同元素时会触发,参数是当前选中元素的行数
itemClicked(QListWidgetltem* item) 点击某个元素时触发
itemDoubleClicked(QListWidgetltem*item) 双击某个元素时触发
itemEntered(QListWidgetltem*item) 鼠标进入元素时触发

在上述介绍中,涉及到一个关键的类,QListwidgetItem这个类表示 QListwidget 中的一个元素核心方法如下,本质上就是一个"文本+图标"构成的.

方法 说明
setFont 设置字体
setlcon 设置图标
setHidden 设置隐藏
setSizeHint 设置尺寸
setSelected 设置是否选中
setText 设置文本
setTextAlignment 设置文本对齐方式

代码示例: 使用 ListWidget:新增按钮列表中的数据,删除按钮删除列表中的数据

  1. 在界面上创建一个 ListView,右键=>变形为=> Listwidget,再创建一个 lineEdit 和 两个按钮
    注意:ListWidget 是 ListView 的子类,功能比 ListView 更丰富.咱们使用Listwidget 即可
  1. 编写 widget.cpp, 在构造函数中添加初始元素
cpp 复制代码
Widget::Widget(QWidget *parent)
	: QWidget(parent)
	, ui(new Ui::Widget)
{
	ui->setupUi(this);
	ui->listWidget->addItem("C++");
	ui->listWidget->addItem("Java");
	ui->listWidget->addItem("Python");
}
  1. 编写 listWidget的 slot 函数
    此处需要判定 current 和 previous 非空.初始情况下是没有元素选中的,就导致这俩指针可能是 NULL.
cpp 复制代码
// 通过ListWidget的信号感受的发生的变化
void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
    if(current !=nullptr)
    {
        qDebug()<<"当前选中的元素"<<current->text();
    }
    if(previous != nullptr)
    {
        qDebug()<<"上次选中的元素"<<previous->text();
    }
}
  1. 编写按钮的 slot 函数
cpp 复制代码
void Widget::on_pushButton_insert_clicked()
{
    // 先获取框中的内容
    QString s=ui->lineEdit->text();

    // 将框中的内容加入到ListWidget
    ui->listWidget->addItem(s);
}

void Widget::on_pushButton_erase_clicked()
{
    // 获取ListWidget中选中的行
    int row=ui->listWidget->currentRow();

    if(row<0)
    {
        return;
    }
    // 将框中的内容到ListWidget 删除
    ui->listWidget->takeItem(row);
}
  1. 执⾏程序, 观察效果. 可以新增元素, 选中元素, 删除元素

1.2 QTableWidget

使用 QTablewidget 表示一个表格控件,一个表格中包含若干行,每一行又包含若干列 .表格中的每个单元格,是一个 QTablewidgetItem 对象

QTablewidget 核心方法

方法 说明
item(int row, int column) 根据行数列数获取指定的 OTablewidgetItem*
setltem(int row, int column,QTablewidget*) 根据行数列数设置表格中的元素
currentltem() 返回被选中的元素 QTableWidgetltem
currentRow() 返回被选中元素是第几行
currentColumn() 返回被选中元素是第几列
row(QTableWidgetltem* ) 获取指定 item 是第几行
column(QTableWidgetltem* ) 获取指定 item 是第几列
rowCount() 获取行数
columnCount() 获取列数
insertRow(int row) 在第 row 行处插入新行
insertColumn(int column) 在第 column 列插入新列
removeRow(int row) 删除第 row 行
removeColumn(int column) 删除第 column列
setHorizontalHeaderltem(intcolumn, QTableWidget*) 设置指定列的表头
setVerticalHeaderltem(int row,QTableWidget*) 设置指定行的表头

核心信号OTableWidgetItem

信号 说明
cellClicked(int row, int column) 点击单元格时触发
cellDoubleClicked(int row, intcolumn) 双击单元格时触发
cellEntered(int row, int column) 鼠标进入单元格时触发
currentCellChanged(int row, intcolumn, int previousRow, intpreviousColumn) 选中不同单元格时触发

QTableWidgetItem 核心方法

方法 说明
row() 获取当前是第几行
column() 获取当前是第几列
setText(const QString&) 设置文本
setTextAlignment(int) 设置文本对齐
setlcon(const Qlcon&) 设置图标
setSelected(bool) 设置被选中
setSizeHints(const OSize&) 设置尺寸
setFont(const QFont&) 设置字体

代码示例:使用 QTablewidget:用按钮新增和删除行和列

  1. 在界面上创建 QTablewidget 和 三个按钮,一个输入框
    注意:QTablewidget 是 QTableView 的子类,功能比 QTableView 更丰富.咱们使用QTablewidget 即可
  2. 编写 widget.cpp 构造函数,构造表格中的初始数据
cpp 复制代码
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);

    // 设置水平的表头
    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("1001"));
    ui->tableWidget->setItem(0,1,new QTableWidgetItem("张三"));
    ui->tableWidget->setItem(0,2,new QTableWidgetItem("20"));

    ui->tableWidget->setItem(1,0,new QTableWidgetItem("1002"));
    ui->tableWidget->setItem(1,1,new QTableWidgetItem("李四"));
    ui->tableWidget->setItem(1,2,new QTableWidgetItem("30"));

    ui->tableWidget->setItem(2,0,new QTableWidgetItem("1003"));
    ui->tableWidget->setItem(2,1,new QTableWidgetItem("王五"));
    ui->tableWidget->setItem(2,2,new QTableWidgetItem("40"));

}
  1. 编写按钮的 slot 函数
cpp 复制代码
void Widget::on_pushButton_addRow_clicked()
{
    // 获得当前表格的总行数
    int curRow=ui->tableWidget->rowCount();

    // 在最后一行新增
    // 新增的是下标是这一行
    ui->tableWidget->insertRow(curRow);
}

void Widget::on_pushButton_subrow_clicked()
{
    // 获得当前选中的行
    int curRow=ui->tableWidget->currentRow();

    // 删除此行
    ui->tableWidget->removeRow(curRow);
}

void Widget::on_pushButton_addcol_clicked()
{
    // 获得当前表格的总列数
    int curCol=ui->tableWidget->columnCount();

    // 在最后一列新增
    // 新增的是下标是这一列
    ui->tableWidget->insertColumn(curCol);

    // 给这一列设置列名
    const QString &s=ui->lineEdit->text();
    ui->tableWidget->setHorizontalHeaderItem(curCol,new QTableWidgetItem(s));

}

void Widget::on_pushButton_subcol_clicked()
{
    // 获得当前选中的列
    int curCol=ui->tableWidget->currentColumn();

    // 删除此列
    ui->tableWidget->removeColumn(curCol);
}
  1. 执⾏程序, 即可完成表格的基本操作

    默认情况下,单元格中的内容直接就是可编辑的如果不想让用户编辑,可以设置 ui->tablewidget-setEditTriggers(QAbstractItemView::NoEditTriggers);

1.3 QTreeWidget

使用 QTreewidget 表示一个树形控件,里面的每个元素,都是一个 QTreewidgetItem,每个QTreewidgetItem 可以包含多个文本和图标,每个文本/图标为一个 列.可以给 QTreewidget 设置顶层节点(顶层节点可以有多个),然后再给顶层节点添加子节点,从而构成树形结构.

QTreewidget 核心方法

方法 说明
clear 清空所有子节点
addTopLevelltem(QTreeWidgetltem* item) 新增顶层节点
topLevelltem(int index) 获取指定下标的顶层节点
topLevelltemCount() 获取顶层节点个数
indexOfTopLevelltem(QTreeWidgetltem* item) 查询指定节点是顶层节点中的下标
takeTopLevelltem(int index) 删除指定的顶层节点.返回 QTreeWidgetltem*表示被删除的元素
currentltem() 获取到当前选中的节点,返回 QTreeWidgetltem
setCurrentltem(OTreeWidgetltem*item) 选中指定节点
setExpanded(bool) 展开/关闭节点
setHeaderLabel(const QString& text) 设置 TreeWidget 的 header 名称.

QTreeWidget 核心信号

信号 说明
currentltemChanged(QTreeWidgetltemcurrent, QTreeWidgetltem old) 切换选中元素时触发
itemClicked(QTreeWidgetltem* item, int col) 点击元素时触发
itemDoubleClicked(QTreeWidgetltem* item,int col) 双击元素时触发
itemEntered(QTreeWidgetltem* item, int col) 鼠标进入时触发
itemExpanded(QTreeWidgetltem* item) 元素被展开时触发
itemCollapsend(QTreeWidgetltem*item) 元素被折叠时触发

QTreeWidgetItem 核心属性

属性 说明
text 持有的文本
textAlignment 文本对齐方式
icon 持有的图表
font 文本字体
hidden 是否隐藏
disabled 是否禁用
expand 是否展开
sizeHint 尺寸大小
selected 是否选中

QTreeWidgetItem 核心方法

方法 说明
addChild(QTreeWidgetltem* child) 新增子节点
childCount() 子节点的个数
child(int index) 获取指定下标的子节点.返回 QTreeWidgetltem*
takeChild(int index) 删除对应下标的子节点
removeChild(QTreeWidgetltem*child) 删除对应的子节点
parent() 获取该元素的父节点

代码示例: 使用 QTreewidget:

  1. 在界面上创建一个 TreeView,右键=>变形为=>TreeWidget,再创建一个lineEdit 和 两个按纽
    注意:TreeWidget是 TreeView 的子类,功能比 TreeView 更丰富,咱们使用 TreeWidget即可
  2. 编写代码, 构造初始数据
cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 新增顶层节点
    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 *item4=new QTreeWidgetItem();
    item4->setText(0,"中华田园猫");
    item1->addChild(item4);

    QTreeWidgetItem *item5=new QTreeWidgetItem();
    item5->setText(0,"布偶猫");
    item1->addChild(item5);

    QTreeWidgetItem *item6=new QTreeWidgetItem();
    item6->setText(0,"旋螺猫");
    item1->addChild(item6);
}
  1. 编写代码, 实现按钮的 slot 函数
cpp 复制代码
void Widget::on_pushButton_clicked()
{
    // 先获取文本框中的内容
    QString s=ui->lineEdit->text();

    // 构造节点对象
    QTreeWidgetItem *item=new QTreeWidgetItem();
    item->setText(0,s);

    // 节点添加到相应的顶层节点中
    ui->treeWidget->addTopLevelItem(item);
}

void Widget::on_pushButton_additem_clicked()
{
    // 先获取文本框中的内容
    QString s=ui->lineEdit->text();

    // 构造节点对象
    QTreeWidgetItem *item=new QTreeWidgetItem();
    item->setText(0,s);

    // 获取选中的元素
    QTreeWidgetItem *im=ui->treeWidget->currentItem();
    im->addChild(item);


}

void Widget::on_pushButton_subitem_clicked()
{
    // 先获取选中的节点
    QTreeWidgetItem *item=ui->treeWidget->currentItem();
    if(item==nullptr)
    {
        return;
    }

    // 删除该节点,要获取此节点的父亲节点
    QTreeWidgetItem *parent= item->parent();

    if(parent==nullptr)
    {
        // 顶层节点
        // 获取顶层节点的下标
        int index=ui->treeWidget->indexOfTopLevelItem(item);
        ui->treeWidget->takeTopLevelItem(index);
    }
    else
    {
        // 不是顶层节点
        parent->removeChild(item);
    }

}
  1. 执⾏程序, 可以针对树形框进⾏编辑.

2. 容器类控件

2.1 QGroupBox

使用 QGroupBox 实现一个带有标题的分组框 ,可以把其他的控件放到里面作为一组,这样看起来能更好看一点.

注意,不要把 QGroupBox 和 QButtonGroup 混淆 ,(之前在介绍 QRadionButton 的时候提

到了QButtonGroup ).

核心属性

属性 说明
title 分组框的标题
alignment 分组框内部内容的对齐方式
flat 是否是"扁平"模式
checkable 是否可选择. 设为 true,则在 title 前方会多出一个可勾选的部分,
checked 描述分组框的选择状态(前提是 checkable 为 true)

2.2 QTabWidget

使用 QTabwidget 实现一个带有标签页的控件,可以往里面添加一些 widget.进一步的就可以通过标签页来切换.

核心属性

属性 说明
tabPosition 标签页所在的位置 * North 上方 * South 下方 * West 左侧 * East 右侧
currentindex 当前选中了第几个标签页(从0开始计算)
currentTabText 当前选中的标签页的文本
currentTabName 当前选中的标签页的名字
currentTablcon 当前选中的标签页的图标
currentTabToolTip 当前选中的标签页的提示信息
tabsCloseable 标签页是否可以关闭
movable 标签页是否可以移动

核心信号

属性 说明
currentChanged(int) 在标签页发生切换时触发,参数为被点击的选项卡编号,
tabBarClicked(int) 在点击选项卡的标签条的时候触发.参数为被点击的选项卡编号
tabBarDoubleClicked(int) 在双击选项卡的标签条的时候触发,参数为被点击的选项卡编号
tabCloseRequest(int) 在标签页关闭时触发.参数为被关闭的选项卡编号

代码示例:使用标签页管理多组控件,按钮新增标签页,删除标签页

  1. 在界面上创建一个 QTabwidget,和两个按钮按钮的 objectName 为pushButton_add 和 pushButton_remove
  2. 编写 widget.cpp,进行初始化,给标签页中放个简单的 label
    注意新创建的 label的父元素,是 ui->tab 和 ui->tab 2 .Qt中使用父子关系决定该控件"在哪里"
cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 创建2个按钮来实现新增标签页,删除标签页

    // 在每一个标签页中添加标签
    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);

}
  1. 编写按钮的 slot 函数
  • 获取到标签页的个数.使用count()
  • 使⽤ addTab 新增标签⻚.
  • 使⽤ removeTab 删除标签⻚.
  • 使⽤ currentIndex 获取到当前标签⻚的下标.
  • 使⽤ setCurrentIndex 切换当前标签⻚
cpp 复制代码
void Widget::on_pushButton_clicked()
{
    // 获取现存标签页的总数
    int count=ui->tabWidget->count();

    // 新增标签页
    // 创建一个标签页对象
    QWidget *t=new QWidget();
    ui->tabWidget->addTab(t,QString("Tab") + QString::number(count+1));

    // 在新增的标签页中加入标签
    QLabel *label = new QLabel(t);
    label->setText(QString("这是标签页")+ QString::number(count+1));

    // 新增的标签页要自动打开被选中,将新增的标签页进行设置为选中
    ui->tabWidget->setCurrentWidget(t);
}

void Widget::on_pushButton_2_clicked()
{
    // 获取选中的标签页
    int index=ui->tabWidget->currentIndex();
    // 进行删除
    ui->tabWidget->removeTab(index);
}
  1. 运行程序,观察效果
    点击新建标签页,可以创建出新的标签
    点击删除当前标签页,可以删除标签

3. 布局管理器

之前使用 Qt 在界面上创建的控件,都是通过"绝对定位"的方式来设定的,也就是每个控件所在的位置,都需要计算坐标,最终通过 setGeometry 或者 move 方式摆放过去 .

这种设定方式其实并不方便,尤其是界面如果内容比较多,不好计算,而且一个窗口大小往往是可以调整的,按照绝对定位的方式,也无法自适应窗口大小,因此 Qt引入"布局管理器"(Layout)机制,来解决上述问题,

3.1 QVBoxLayout(垂直布局)

使用 QVBoxLayout 表示垂直的布局管理器

核心属性

属性 说明
layoutLeftMargin 左侧边距
layoutRightMargin 右侧边距
layoutTopMargin 上方边距
layoutBottomMargin 下方边距
layoutSpacing 相邻元素之间的间距

Layout 只是⽤于界⾯布局, 并没有提供信号

代码示例: 创建两个 QVBoxLayout

  1. 在界面上创建两个 QVBoxLayout,每个 QVBoxLayout 各放三个按钮
  2. 运行程序,可以看到这些按钮已经自动排列好,只不过当前这些按钮的位置不能随着窗口大小自动变化

3.2 QHBoxLayout(水平布局)

使用 QHBoxLayout 表示垂直的布局管理器.

核心属性(和 QVBoxLayout 属性是一致的)

属性 说明
layoutLeftMargin 左侧边距
layoutRightMargin 右侧边距
layoutTopMargin 上方边距
layoutBottomMargin 下方边距
layoutSpacing 相邻元素之间的间距

代码示例: 嵌套的layout

  1. 在代码中创建以下内容
    使用 addLayout 给layout 中添加子layout,
cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 创建一个垂直布局管理器
    QVBoxLayout *cayout=new QVBoxLayout();

    // 创建两个按钮
    QPushButton*button1=new QPushButton("按钮1");
    QPushButton*button2=new QPushButton("按钮2");

    // 将按钮设置到垂直管理器中
    cayout->addWidget(button1);
    cayout->addWidget(button2);


    // 创建一个水平管理器中
    QHBoxLayout *hayout=new QHBoxLayout();


    QPushButton*button3=new QPushButton("按钮3");
    QPushButton*button4=new QPushButton("按钮4");

    // 将按钮设置到水平管理器中
    hayout->addWidget(button3);
    hayout->addWidget(button4);

    // 水平管理器添加到垂直管理器
    cayout->addLayout(hayout);

    // 垂直管理器设置到窗口中
    this->setLayout(cayout);
}
  1. 执⾏程序,观察结果

3.3 QGridLayout

Qt中还提供了 QGridLayout 用来实现网格布局的效果,可以达到 M*N的这种网格的效果.

核⼼属性

属性 说明
layoutLeftMargin 左侧边距
layoutRightMargin 右侧边距
layoutTopMargin 上方边距
layoutBottomMargin 下方边距
layoutHorizontalSpacing 相邻元素之间水平方向的间距
layoutVerticalSpacing 相邻元素之间垂直方向的间距
layoutRowStretch 行方向的拉伸系数
layoutColumnStretch 列方向的拉伸系数

代码示例: 使用 QGridLayout 管理元素

  1. 代码中创建 QGridLayout 和4个按钮,
    使用 addwidget 添加控件到布局管理器中,但是添加的同时会指定两个坐标,表示放在第几行,第几列.
cpp 复制代码
Widget::Widget(QWidget *parent)
	: QWidget(parent)
	, ui(new Ui::Widget)
{
	ui->setupUi(this);
	
	// 创建 4 个按钮
	QPushButton* btn1 = new QPushButton("按钮1");
	QPushButton* btn2 = new QPushButton("按钮2");
	QPushButton* btn3 = new QPushButton("按钮3");
	QPushButton* btn4 = new QPushButton("按钮4");
	
	// 创建⽹格布局管理器, 并且添加元素
	QGridLayout* layout = new QGridLayout();
	layout->addWidget(btn1, 0, 0);
	layout->addWidget(btn2, 0, 1);
	layout->addWidget(btn3, 1, 0);
	layout->addWidget(btn4, 1, 1);
	
	// 设置 layout 到窗⼝中.
	this->setLayout(layout);
}
  1. 执行代码,观察效果.可以看到当前的这几个按钮是按照2行2列的方式排列的,
  2. 如果调整⾏列坐标为下列代码
cpp 复制代码
// 创建⽹格布局管理器, 并且添加元素
QGridLayout* layout = new QGridLayout();
layout->addWidget(btn1, 0, 0);
layout->addWidget(btn2, 0, 1);
layout->addWidget(btn3, 0, 2);
layout->addWidget(btn4, 0, 3);

执⾏代码, 可以看到这⼏个按钮都在同⼀⾏了. 相当于 QHBoxLayout

  1. 如果调整⾏列坐标为下列代码
cpp 复制代码
QGridLayout* layout = new QGridLayout();
layout->addWidget(btn1, 1, 0);
layout->addWidget(btn2, 2, 0);
layout->addWidget(btn3, 3, 0);
layout->addWidget(btn4, 4, 0);

3.4 QFormLayout

除了上述的布局管理器之外,Qt还提供了 QFormLayout,属于是 QGridLayout 的特殊情况,专门用于实现两列表单的布局.
这种表单布局多用于让用户填写信息的场景,左侧列为提示,右侧列为输入框.

代码示例:使用 QFormLayout 创建表单

  1. 编写代码,创建 QFormLayout,以及三个label和三个 lineEdit
  • 使用 addRow 方法来添加一行,每行包含两个控件,第一个控件固定是 QLabel/文本,第二个控件则可以是任意控件
  • 如果把第一个参数填写为 NULL,则什么都不显示,
cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 设置成 3 行 2列的表单
    QFormLayout *layout=new QFormLayout();
    this->setLayout(layout);

    QLabel *label1=new QLabel("标签1");
    QLabel *label2=new QLabel("标签1");
    QLabel *label3=new QLabel("标签1");

    QLineEdit *edit1=new QLineEdit();
    QLineEdit *edit2=new QLineEdit();
    QLineEdit *edit3=new QLineEdit();


    // 上述控件添加到表单布局中
    layout->addRow(label1,edit1);
    layout->addRow(label2,edit2);
    layout->addRow(label3,edit3);

    QPushButton *button=new QPushButton("提交");
    layout->addRow(button);

}
  1. 执⾏程序, 可以看到以下结果

3.5 QSpacerItem

使用布局管理器的时候,可能需要在控件之间,添加一段空白.就可以使用 QSpacerItem 来表示.

核心属性

属性 说明
width 宽度
height 高度
hData 水平方向的 sizePolicy * QSizePolicy::Ignored:忽略控件的尺寸,不对布局产生影响。 * QSizePolicy::Minimum:控件的最小尺寸为固定值,布局时不会超过该值。 * QSizePolicy::Maximum:控件的最大尺寸为固定值,布局时不会小于该值。QSizePolicy::Preferred:控件的理想尺寸为固定值,布局时会尽量接近该值。 * QSizePolicy::Expanding:控件的尺寸可以根据空间调整,尽可能占据更多空间。 * QSizePolicy::Shrinking:控件的尺寸可以根据空间调整,尽可能缩小以适应空间。
vData 垂直方向的 sizePolicy 选项同上.

代码示例: 创建一组左右排列的按钮

  1. 在界面上创建一个 QVBoxLayout,并添加两个按钮
cpp 复制代码
Widget::Widget(QWidget *parent)
	: QWidget(parent)
	, ui(new Ui::Widget)
{
	ui->setupUi(this);
	QHBoxLayout* layout = new QHBoxLayout();
	this->setLayout(layout);
	QPushButton* btn1 = new QPushButton("按钮1");
	QPushButton* btn2 = new QPushButton("按钮2");
	layout->addWidget(btn1);
	layout->addWidget(btn2);
}
  1. 直接运行程序,可以看到两个按钮是紧挨着的
  2. 在两个按钮中间添加⼀个 spacer
cpp 复制代码
Widget::Widget(QWidget *parent)
	: QWidget(parent)
	, ui(new Ui::Widget)
{
	ui->setupUi(this);
	QHBoxLayout* layout = new QHBoxLayout();
	this->setLayout(layout);
	QPushButton* btn1 = new QPushButton("按钮1");
	QPushButton* btn2 = new QPushButton("按钮2");
	
	// 创建 Spacer
	QSpacerItem* spacer = new QSpacerItem(200, 20);
	layout->addWidget(btn1);
	
	// 在两个 widget 中间添加空⽩
	layout->addSpacerItem(spacer);
	layout->addWidget(btn2);
}
  1. 运行程序,观察代码效果,可以看到两个按钮之间已经存在了间隔了调整 QSpacerltem 不同的尺寸,即可看到不同的间距
相关推荐
懒大王爱吃狼1 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
秃头佛爷2 小时前
Python学习大纲总结及注意事项
开发语言·python·学习
待磨的钝刨2 小时前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
XiaoLeisj4 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
励志成为嵌入式工程师5 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉5 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer5 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq5 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
记录成长java7 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山7 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js