1. 手动拖放

通过在 Qt Designer 中手动拖放控件,可以快速实现界面布局,如下图所示:

这种方式对初学者非常友好,可以快速上手开发一个界面,增加成就感。但我们需要知道,拖放布局不是 Qt 布局的全部,这种方式仅适合简单的界面布局。

在实际的项目开发中,界面上的控件会比上面示例中的多得多,布局也会更加复杂,而且界面通常还需要反复地调整。在这种情况下,如果继续通过手动拖放的方式来进行布局,在每次界面调整时,我们都需要打破(分拆)原有的布局,并在修改完成之后重新进行布局,可能还需要重新设置布局的 Spacing 和 ContentsMargins,每一次修改都非常费劲。

题外话:

手动拖放控件对手的稳定性要求较高,可能手稍一抖,整个布局就错乱了,又得还原了重新来。

2. 代码布局

我通常使用代码的方式来进行 Qt 界面布局,例如下面的代码实现了与上面示例一样的布局效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
QLabel* lblUserName = new QLabel("用户名: ");
QLabel* lblPassword = new QLabel("密码: ");
QLineEdit* editUserName = new QLineEdit();
QLineEdit* editPassword = new QLineEdit();
QPushButton* btnLogin = new QPushButton("登录");
QPushButton* btnRegister = new QPushButton("注册");

QHBoxLayout* hUserName = new QHBoxLayout();
hUserName->addWidget(lblUserName);
hUserName->addWidget(editUserName);

QHBoxLayout* hPassword = new QHBoxLayout();
hPassword->addWidget(lblPassword);
hPassword->addWidget(editPassword);

QHBoxLayout* hButton = new QHBoxLayout();
hButton->addStretch();
hButton->addWidget(btnRegister);
hButton->addWidget(btnLogin);
hButton->addStretch();

QVBoxLayout* vMain = new QVBoxLayout();
vMain->addLayout(hUserName);
vMain->addLayout(hPassword);
vMain->addStretch();
vMain->addLayout(hButton);

this->setLayout(vMain);

大家看到上面代码后,第一感觉肯定是“我的个老天,这么复杂”,这个可以理解。但这种方式的好处也非常明显,比如灵活性更大,后期调整、复用、维护也更加方便,而且对于自定义控件比较多的界面,这种方式可以直接创建对应类型的实例,不需要在设计器上进行类型提升。

3. 布局描述语言

我在这里不是为了创造一种新的语言,而是受到了 Flutter 界面布局方式的启发,对 Qt 的布局进行了封装,简化了上述布局代码。

下面是上述示例简化后的布局代码:

1
2
3
4
5
6
7
auto layout = VBox(
HBox(lblUserName, editUserName),
HBox(lblPassword, editPassword),
Stretch(),
HBox(Stretch(), btnRegister, btnLogin, Stretch()));

setLayout(layout);

从代码量来看,明显少了很多,而且我们还可以通过代码的层次结构快速看出界面的布局结构。

在此省略了 VBox、HBox 等类的实现代码,如果您对上述 Qt 布局方式的具体实现感兴趣,可以在下面留言或者联系我。