容器类控件和布局管理器

1. 容器类控件

1.1 Group Box

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

  • 注意:不要把 QGroupBox 和 QButtonGroup 混淆。(之前在介绍 QRadionButton 的时候提到了 QButtonGroup )。

(2)核心属性:

属性说明
title分组框的标题。
alignment分组框内部内容的对齐方式。
flat是否是 “扁平” 模式。
checkable是否可选择。设为 true, 则在 title 前方会多出⼀个可勾选的部分。
checked描述分组框的选择状态 (前提是 checkable 为 true) 。
  • 分组框只是⼀个用来 “美化界面” 这样的组件,并不涉及到用户交互和业务逻辑。属于 “锦上添花”。

(3)代码示例:给麦当劳案例加上分组框。

  • 在界面上创建三个分组框,并且在分组框内部创建下拉框和微调框。


注意:在复制粘贴控件的时候,⼀定要先选中对应的父控件再粘贴。

  • 编写 widget.cpp,添加初始化下拉框的代码。
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("⻨辣鸡翅");
	
	ui->comboBox_3->addItem("可乐");
	ui->comboBox_3->addItem("雪碧");
}
  • 运行程序观察效果:

1.2 Tab Widget

(1)使用 QTabWidget 实现⼀个带有标签页的控件,可以往里面添加一些 widget。进一步的就可以通过标签页来切换。 核心属性如下:

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

(2)核心信号:

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

(3)代码示例:使用标签页管理多组控件。

  • 在界面上创建⼀个 QTabWidget 和两个按钮。
  • 按钮的 objectName 为 pushButton_add 和 pushButton_remove。

  • 注意:
    • QTabWidget 中的每个标签页都是⼀个 QWidget 。
    • 点击标签页,就可以直接切换。
    • 右键 QTabWidget,可以添加标签页或者删除标签页。
  • 编写 widget.cpp,进行初始化,给标签页中放个简单的 label。
    • 注意新创建的 label 的父元素是 ui->tab 和 ui->tab_2 。Qt 中使用父子关系决定该控件 “在哪里”。
QLabel* label = new QLabel(ui->tab);
label->setText("标签⻚1");
label->resize(100, 50);

QLabel* label2 = new QLabel(ui->tab_2);
label2->setText("标签⻚2");
label2->resize(100, 50);
  • 编写按钮的 slot 函数:
    • 使用 count() 获取到标签页的个数.
    • 使用 addTab 新增标签页。
    • 使用 removeTab 删除标签页。
    • 使用 currentIndex 获取到当前标签页的下标.
    • 使用 setCurrentIndex 切换当前标签页。
void Widget::on_pushButton_add_clicked()
{
	// 获取当前有⼏个标签⻚了
	int count = ui->tabWidget->count();
	
	// 创建新的 widget
	QWidget* w = new QWidget();
	ui->tabWidget->addTab(w, QString("Tab ") + QString::number(count + 1));
	
	// 给 widget 中添加 label
	QLabel* label = new QLabel(w);
	label->setText(QString("标签⻚") + QString::number(count + 1));
	label->resize(100, 50);
	
	// 选中这个新的标签⻚
	ui->tabWidget->setCurrentIndex(count);
}

void Widget::on_pushButton_remove_clicked()
{
	// 获取当前标签⻚的下标
	int index = ui->tabWidget->currentIndex();
	
	// 删除这个标签⻚
	ui->tabWidget->removeTab(index);
}
  • 编写 QTabWidget 的 currentChanged 函数。
void Widget::on_tabWidget_currentChanged(int index)
{
	qDebug() << "当前选中标签⻚为: " << index;
}
  • 运行程序观察效果:
    • 点击新建标签页,可以创建出新的标签。
    • 点击删除当前标签页,可以删除标签。
    • 切换标签页时,可以看到 qDebug 打印出的标签页编号。

2. 布局管理器

(1)之前使用 Qt 在界面上创建的控件,都是通过 “绝对定位” 的方式来设定的。

  • 也就是每个控件所在的位置,都需要计算坐标,最终通过 setGeometry 或者 move 方式摆放过去。
  • 这种设定方式其实并不方便。尤其是界面如果内容比较多,不好计算。而且⼀个窗口大小往往是可以调整的,按照绝对定位的方式,也无法自适应窗口大小。
  • 因此 Qt 引入 “布局管理器” (Layout) 机制来解决上述问题。
  • 当然布局管理器并非 Qt 独有。其他的 GUI 开发框架,像 Android,前端等也有类似的机制。

2.1 垂直布局

(1)使用 QVBoxLayout 表示垂直的布局管理器,V 是 vertical 的缩写。核心属性如下:

属性说明
layoutLeftMargin左侧边距。
layoutRightMargin右侧边距。
layoutTopMargin上方边距 。
layoutBottomMargin下方边距。
layoutSpacing相邻元素之间的间距。
  • Layout 只是用于界面布局,并没有提供信号。

(2)代码示例:使用 QVBoxLayout 管理多个控件。

  • 编写代码,创建布局管理器和三个按钮。并且把按钮添加到布局管理器中。
    • 使用 addWidget 把控件添加到布局管理器中。
    • 使用 setLayout 设置该布局管理器到 widget 中。
Widget::Widget(QWidget *parent)
	:QWidget(parent)
	,ui(new Ui::Widget)
{
	ui->setupUi(this);
	
	// 创建三个按钮
	QPushButton* btn1 = new QPushButton("按钮1");
	QPushButton* btn2 = new QPushButton("按钮2");
	QPushButton* btn3 = new QPushButton("按钮3");
	
	// 创建布局管理器, 并且把按钮添加进去
	// 如果创建的时候指定⽗元素为 this, 则后⾯不需要 setLayout ⽅法了.
	QVBoxLayout* layout = new QVBoxLayout();
	layout->addWidget(btn1);
	layout->addWidget(btn2);
	layout->addWidget(btn3);
	
	// 把布局管理器设置到 widget 中
	this->setLayout(layout);
}
  • 运行程序,可以看到此时界面上的按钮就存在于布局管理器中。随着窗口尺寸变化而发生改变。
  • 此时三个按钮的尺寸和位置都是自动计算出来的。

  • 通过上述代码的方式只能给这个 widget 设定⼀个布局管理器。实际上也可以通过 Qt Design 在⼀个窗口中创建多个布局管理器。

(3)代码示例:创建两个 QVBoxLayout。

  • 在界面上创建两个 QVBoxLayout ,每个 QVBoxLayout 各放三个按钮。

  • 运行程序可以看到这些按钮已经自动排列好。只不过当前这些按钮的位置不能随着窗口大小自动变化。

  • 通过 Qt Designer 创建的布局管理器,其实是先创建了⼀个 widget,设置过 geometry 属性的。再把这个 layout 设置到这个 widget 中。
  • 实际上⼀个 widget 只能包含⼀个 layout。
  • 打开 ui 文件的原始 xml,可以看到其中的端倪。
  • 这种情况下 layout 并非是窗口 widget 的布局管理器,因此不会随着窗口大小改变。
<widget class="QWidget" name="verticalLayoutWidget">
	<property name="geometry">
	 <rect>
	  <x>140</x>
	  <y>140</y>
	  <width>141</width>
	  <height>331</height>
	 </rect>
	</property>
	<layout class="QVBoxLayout" name="verticalLayout">
	 <item>
	  <widget class="QPushButton" name="pushButton_3">
	   <property name="text">
		<string>PushButton</string>
	   </property>
	  </widget>
	 </item>
	 <item>
	  <widget class="QPushButton" name="pushButton_2">
	   <property name="text">
		<string>PushButton</string>
	   </property>
	  </widget>
	 </item>
	 <item>
	  <widget class="QPushButton" name="pushButton">
	   <property name="text">
		<string>PushButton</string>
	   </property>
	  </widget>
	 </item>
	</layout>
</widget>

2.2 水平布局

(1)使用 QHBoxLayout 表示垂直的布局管理器。H 是 horizontal 的缩写。核心属性和 QVBoxLayout 属性是一致的。

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

(2)代码示例:使用 QHBoxLayout 管理控件。

  • 编写代码,创建布局管理器和三个按钮。并且把按钮添加到布局管理器中。
Widget::Widget(QWidget *parent)
	:QWidget(parent)
	,ui(new Ui::Widget)
{
	ui->setupUi(this);
	
	// 创建三个按钮
	QPushButton* btn1 = new QPushButton("按钮1");
	QPushButton* btn2 = new QPushButton("按钮2");
	QPushButton* btn3 = new QPushButton("按钮3");
	
	// 创建布局管理器
	QHBoxLayout* layout = new QHBoxLayout();
	layout->addWidget(btn1);
	layout->addWidget(btn2);
	layout->addWidget(btn3);
	
	// 设置 layout 到 widget 上
	this->setLayout(layout);
}
  • 运行程序,可以看到此时界面上的按钮就存在于布局管理器中。随着窗口尺寸变化而发生改变。
  • 此时三个按钮的尺寸和位置都是自动计算出来的。

  • Layout 里面可以再嵌套上其他的 layout,而达到更复杂的布局效果。

(3)代码示例:嵌套的 layout。

  • 在代码中创建以下内容。使用 addLayout 给 layout 中添加子 layout。
Widget::Widget(QWidget *parent)
	:QWidget(parent)
	,ui(new Ui::Widget)
{
	ui->setupUi(this);
	
	// 创建顶层 layout
	QVBoxLayout* layoutParent = new QVBoxLayout();
	this->setLayout(layoutParent);
	
	// 添加两个按钮进去
	QPushButton* btn1 = new QPushButton("按钮1");
	QPushButton* btn2 = new QPushButton("按钮2");
	layoutParent->addWidget(btn1);
	layoutParent->addWidget(btn2);
	
	// 创建⼦ layout
	QHBoxLayout* layoutChild = new QHBoxLayout();
	
	// 添加两个按钮进去
	QPushButton* btn3 = new QPushButton("按钮3");
	QPushButton* btn4 = new QPushButton("按钮4");
	layoutChild->addWidget(btn3);
	layoutChild->addWidget(btn4);
	
	// 把这个⼦ layout 添加到 ⽗ layout 中
	layoutParent->addLayout(layoutChild);
}
  • 执行程序观察结果:

  • 结合 QHBoxLayout 和 QVBoxLayout,就可以做出各种复杂的界面了。

2.3 网格布局

(1)Qt 中还提供了 QGridLayout 用来实现网格布局的效果。可以达到 M * N 的这种网格的效果。核心属性如下:

  • 整体和 QVBoxLayout 以及 QHBoxLayout 相似。但是设置 spacing 的时候是按照垂直水平两个方向来设置的。
属性说明
layoutLeftMargin左侧边距。
layoutRightMargin右侧边距。
layoutTopMargin上方边距。
layoutBottomMargin下方边距。
layoutHorizontalSpacing相邻元素之间水平方向的间距。
layoutVerticalSpacing相邻元素之间垂直方向的间距。
layoutRowStretch行方向的拉伸系数。
layoutColumnStretch列方向的拉伸系数。

(2)代码示例:使用 QGridLayout 管理元素。

  • 代码中创建 QGridLayout 和 4 个按钮。
  • 使用 addWidget 添加控件到布局管理器中。但是添加的同时会指定两个坐标。表示放在第几行,第几列。
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);
}
  • 执行代码观察效果。可以看到当前的这几个按钮是按照 2 行 2 列的方式排列的。

  • 如果调整行列坐标为下列代码:
// 创建⽹格布局管理器, 并且添加元素
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。

  • 如果调整行列坐标为下列代码:
QGridLayout* layout = new QGridLayout();
layout->addWidget(btn1, 1, 0);
layout->addWidget(btn2, 2, 0);
layout->addWidget(btn3, 3, 0);
layout->addWidget(btn4, 4, 0);
  • 执行代码,可以看到这几个按钮都在同一列了。相当于 QVBoxLayout。

  • 任意调整行列,即可看到不同的效果。
// 创建⽹格布局管理器, 并且添加元素
QGridLayout* layout = new QGridLayout();
layout->addWidget(btn1, 0, 0);
layout->addWidget(btn2, 1, 1);
layout->addWidget(btn3, 2, 2);
layout->addWidget(btn4, 3, 3);
  • 运行结果:

  • 编写代码形如:
QGridLayout* layout = new QGridLayout();
layout->addWidget(btn1, 0, 0);
layout->addWidget(btn2, 1, 0);
layout->addWidget(btn3, 2, 0);
layout->addWidget(btn4, 10, 0);
  • 此处也要注意:设置行和列的时候,如果设置的是⼀个很大的值,但是这个值和上一个值之间并没有其他的元素,那么并不会在中间腾出额外的空间。
  • 虽然把 btn4 设置在第 10 行,但是由于 3-9 行没有元素。因此 btn4 仍然会紧挨在 btn3 下方。看起来和上面的 0 1 2 3 的情况是相同的。

(3)代码示例:设置 QGridLayout 中元素的大小比例。

  • 创建 6 个按钮,按照 2 行 3 列的方式排列。
  • 使用 setColumnStretch 设置每⼀列的拉伸系数。
Widget::Widget(QWidget *parent)
	:QWidget(parent)
	,ui(new Ui::Widget)
{
	ui->setupUi(this);
	
	// 创建 6 个按钮
	QPushButton* btn1 = new QPushButton("按钮1");
	QPushButton* btn2 = new QPushButton("按钮2");
	QPushButton* btn3 = new QPushButton("按钮3");
	QPushButton* btn4 = new QPushButton("按钮4");
	QPushButton* btn5 = new QPushButton("按钮5");
	QPushButton* btn6 = new QPushButton("按钮6");
	
	// 创建⽹格布局管理器, 并且添加元素
	QGridLayout* layout = new QGridLayout();
	layout->addWidget(btn1, 0, 0);
	layout->addWidget(btn2, 0, 1);
	layout->addWidget(btn3, 0, 2);
	layout->addWidget(btn4, 1, 0);
	layout->addWidget(btn5, 1, 1);
	layout->addWidget(btn6, 1, 2);
	
	// 设置拉伸⽐例
	// 第 0 列拉伸⽐例设为 1;
	layout->setColumnStretch(0, 1);
	// 第 1 列拉伸⽐例设为 0, 即为固定⼤⼩, 不参与拉伸
	layout->setColumnStretch(1, 0);
	// 第 2 列拉伸⽐例设为 3, 即为第 2 列的宽度是第 0 列的 3 倍
	layout->setColumnStretch(2, 3);
	
	// 设置 layout 到窗⼝中.
	this->setLayout(layout);
}
  • 执行程序,可以看到每⼀列的宽度是不同的。并且随着窗口调整动态变化。

  • 另外,QGridLayout 也提供了 setRowStretch 设置行之间的拉伸系数。
  • 上述案例中,直接设置 setRowStretch 效果不明显,因为每个按钮的高度是固定的。需要把按钮的垂直方向的 sizePolicy 属性设置为 QSizePolicy::Expanding 尽可能填充满布局管理器才能看到效果。

(4)代码示例:设置垂直方向的拉伸系数。

  • 编写代码,创建 6 个按钮,按照 3 行 2 列方式排列。
  • 使用 setSizePolicy 设置按钮的尺寸策略。可选的值如下:
    • QSizePolicy::Ignored:忽略控件的尺寸,不对布局产生影响。
    • QSizePolicy::Minimum:控件的最小尺寸为固定值,布局时不会超过该值。
    • QSizePolicy::Maximum: 控件的最大尺寸为固定值,布局时不会小于该值。
    • QSizePolicy::Preferred:控件的理想尺寸为固定值,布局时会尽量接近该值。
    • QSizePolicy::Expanding:控件的尺寸可以根据空间调整,尽可能占据更多空间。
    • QSizePolicy::Shrinking:控件的尺寸可以根据空间调整,尽可能缩小以适应空间。
Widget::Widget(QWidget *parent)
	:QWidget(parent)
	,ui(new Ui::Widget)
{
	ui->setupUi(this);
	
	// 创建 6 个按钮
	QPushButton* btn1 = new QPushButton("按钮1");
	QPushButton* btn2 = new QPushButton("按钮2");
	QPushButton* btn3 = new QPushButton("按钮3");
	QPushButton* btn4 = new QPushButton("按钮4");
	QPushButton* btn5 = new QPushButton("按钮5");
	QPushButton* btn6 = new QPushButton("按钮6");
	
	// 设置按钮的 sizePolicy, 此时按钮的⽔平⽅向和垂直⽅向都会尽量舒展开
	btn1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	btn2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	btn3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	btn4->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	btn5->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	btn6->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	
	// 创建⽹格布局管理器, 并且添加元素
	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->addWidget(btn5, 2, 0);
	layout->addWidget(btn6, 2, 1);
	
	// 设置拉伸⽐例
	// 第 0 ⾏拉伸⽐例设为 1;
	layout->setRowStretch(0, 1);
	// 第 1 ⾏拉伸⽐例设为 0, 即为固定⼤⼩, 不参与拉伸
	layout->setRowStretch(1, 0);
	// 第 2 ⾏拉伸⽐例设为 3, 即为第 2 ⾏的宽度是第 0 ⾏的 3 倍
	layout->setRowStretch(2, 3);
	
	// 设置 layout 到窗⼝中.
	this->setLayout(layout);
}
  • 执行代码观察效果。 此时的按钮垂直方向都舒展开了。并且调整窗口尺寸,也会按照设定的比例同步变化。

  • 总的来说:使用 QGridLayout 能够代替很多 QHBoxLayout 和 QVBoxLayout 嵌套的场景。毕竟嵌套的代码写起来是比较麻烦的。
  • 另外不要忘了, QGridLayout 里面也能嵌套 QHBoxLayout 和 QVBoxLayout,QHBoxLayout 和 QVBoxLayout 里面也能嵌套 QGridLayout 。
  • 灵活使用上述布局管理器,就可以实现出任意的复杂界面。

2.4 表单布局

(1)除了上述的布局管理器之外,Qt 还提供了 QFormLayout,属于是 QGridLayout 的特殊情况,专门用于实现两列表单的布局。

  • 这种表单布局多用于让用户填写信息的场景。左侧列为提示,右侧列为输入框。

(2)代码示例:使用 QFormLayout 创建表单。

  • 编写代码,创建 QFormLayout,以及三个 label 和三个 lineEdit。
  • 使用 addRow 方法来添加一行。每行包含两个控件。第一个控件固定是 QLabel / 文本,第二个控件则可以是任意控件。
  • 如果把第⼀个参数填写为 NULL,则什么都不显示。
Widget::Widget(QWidget *parent)
	:QWidget(parent)
	,ui(new Ui::Widget)
{
	ui->setupUi(this);
	
	// 创建 layout
	QFormLayout* layout = new QFormLayout();
	this->setLayout(layout);
	
	// 创建三个 label
	QLabel* label1 = new QLabel("姓名");
	QLabel* label2 = new QLabel("年龄");
	QLabel* label3 = new QLabel("电话");
	
	// 创建三个 lineEdit
	QLineEdit* lineEdit1 = new QLineEdit();
	QLineEdit* lineEdit2 = new QLineEdit();
	QLineEdit* lineEdit3 = new QLineEdit();
	
	// 创建⼀个提交按钮
	QPushButton* btn = new QPushButton("提交");
	
	// 把上述元素添加到 layout 中
	layout->addRow(label1, lineEdit1);
	layout->addRow(label2, lineEdit2);
	layout->addRow(label3, lineEdit3);
	layout->addRow(NULL, btn);
}
  • 执行程序,可以看到以下结果:

2.5 Spacer

(1)使用布局管理器的时候可能需要在控件之间添加⼀段空白。就可以使用QSpacerItem 来表示。 核心属性如下:

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

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

  • 在界面上创建⼀个 QVBoxLayout,并添加两个按钮。
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);
}
  • 直接运行程序可以看到两个按钮是紧挨着的:

  • 在两个按钮中间添加⼀个 spacer:
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);
}
  • 运行程序观察代码效果。可以看到两个按钮之间已经存在了间隔了。调整 QSpacerItem 不同的尺寸即可看到不同的间距。

  • 在 Qt Designer 中也可以直接给界面上添加 spacer。

3. 容器类控件和布局管理器总结

(1)容器类控件:容器类控件用于组织和容纳其他控件,帮助构建结构化的界面布局。

  1. QGroupBox(分组框):
    • 功能:将相关控件分组,并显示标题边框。
  2. QTabWidget(标签页容器):
    • 功能:通过标签页切换多个子界面,节省空间。
    • 信号:
      • currentChanged(int index):页签切换时触发。

(2)布局管理器总结:布局管理器用于自动排列控件位置,适配不同屏幕尺寸和窗口大小。

  1. QHBoxLayout(水平布局):
    • 功能:水平排列控件(从左到右)。
  2. QVBoxLayout(垂直布局):
    • 功能:垂直排列控件(从上到下)。
  3. QGridLayout(网格布局):
    • 功能:按行列网格排列控件,支持跨行/列。
  4. QFormLayout(表单布局):
    • 功能:两列布局(标签 + 输入控件),适合表单设计。

(3)容器与布局选择建议:

  • 容器控件:
    • 分组显示 → QGroupBox
    • 分页切换 → QTabWidget
    • 长内容滚动 → QScrollArea
    • 动态页面 → QStackedWidget
    • 可停靠面板 → QDockWidget
  • 布局管理器:
    • 简单横向排列 → QHBoxLayout
    • 简单纵向排列 → QVBoxLayout
    • 复杂网格 → QGridLayout
    • 表单设计 → QFormLayout
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Smile丶凉轩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值