Qt 布局之一:布局初探
前言
对于一个完善的软件,布局管理是必不可少的。 无论是想要界面中部件有一个很整齐的排列,还是想要界面能适应窗口的大小变化,都要进行布局管理。Qt 提供了 QLayout 类及其子类来作为布局管理器,它们可以实现常用的布局管理功能。
水平、垂直、网格、表单布局
为窗口提供一个好布局的最佳方式是使用内置的布局管理器:QHBoxLayout、QVBoxLayout、QGridLayout 和 QFormLayout。这些类都派生自 QLayout,QLayout 又派生自 QObject(非 QWidget),布局窗口自动地把子窗口按照它们被构造地顺序进行布局。要生成更复杂的布局,可以在其它布局里面嵌入另一个布局。
(1)QHBoxLayout:把子窗口从左到右排列在一个水平行上。
QWidget *window = new QWidget;
QPushButton *button1 = new QPushButton("One");
QPushButton *button2 = new QPushButton("Two");
QPushButton *button3 = new QPushButton("Three");
QPushButton *button4 = new QPushButton("Four");
QPushButton *button5 = new QPushButton("Five");
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);
layout->addWidget(button4);
layout->addWidget(button5);
window->setLayout(layout);
window->show();
效果如下所示:
(2)QVBoxLayout:把子窗口从上到下排列在一个垂直列上。
...
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);
layout->addWidget(button4);
layout->addWidget(button5);
...
使用与 QHBoxLayout 区别不大。效果如下所示:
(3)QGridLayout:把子窗口排列在一个二维的网格中,窗口可占据多个单元格。
...
QGridLayout *layout = new QGridLayout;
layout->addWidget(button1, 0, 0);
layout->addWidget(button2, 0, 1);
layout->addWidget(button3, 1, 0, 1, 2);
layout->addWidget(button4, 2, 0);
layout->addWidget(button5, 2, 1);
...
对于 QGridLayout 有点不同,因为需要指定子控件的行和列的位置。第三个 QPushButton 占据 2 列。通过指定 QGridLayout:: addWidget() 的第五个参数为 2 来实现。效果如下所示:
(4)QFormLayout:把子窗口按照 “标签-输入框” 的形式排列在两列。
QWidget *window = new QWidget;
QPushButton *button1 = new QPushButton("One");
QLineEdit *lineEdit1 = new QLineEdit();
QPushButton *button2 = new QPushButton("Two");
QLineEdit *lineEdit2 = new QLineEdit();
QPushButton *button3 = new QPushButton("Three");
QLineEdit *lineEdit3 = new QLineEdit();
QFormLayout *layout = new QFormLayout;
layout->addRow(button1, lineEdit1);
layout->addRow(button2, lineEdit2);
layout->addRow(button3, lineEdit3);
window->setLayout(layout);
window->show();
QFormLayout 将在一行上添加两个控件,通常是 QLabel 和 QLineEdit。在同一行中添加 QLabel 和 QLineEdit,将把 QLineEdit 设置为 QLabel 的伙伴。下面的代码将使用 QFormLayout 将三个 QPushButton 和相应 QLineEdit 排列起来。效果如下所示:
使用布局提示
当使用布局的时候,构建子控件的时候不需要指定 parent,布局将会自动的指定 parent(使用QWidget::setParent()),使它们成为安装了该布局的界面的子控件。
注意:布局中的控件是安装了该布局的界面的子控件,而非布局自身的,控件只能以控件作为parent,不能是布局。
也可以在布局中使用 addLayout() 来添加布局,内部的布局就会变成它的子布局。
为布局添加控件的过程分析
当添加一个控件到一个布局中,布局过程工作如下:
-
所有的控件将最初根据它们的 QWidget::sizePolicy() 和 QWidget::sizeHint() 而被分配到一定空间中。
-
如果任何一个控件有一个伸展因素设置,而且数值大于零,那么它们就会被根据它们的伸展因素的比例分配空间。
-
如果任何一个控件有一个伸展因素设置而且数值为零,那么只有当其它控件不再需要空间的时候才会得到更多的空间。在这当中,空间会首先被根据延展大小策略分配给控件。
-
任何控件被分配的空间的大小如果小于它们的最小大小(或者是在没有规定最小大小时的最小大小的提示),它们就会被按它们所需要的最小大小分配空间。(如果控件的伸展因素是它们的决定因素的情况下,它们不必有最小大小或者最小大小的提示。)
-
任何控件被分配的空间的大小如果大于它们的最大大小,它们就会被按它们所需要的最大大小分配空间。(如果控件的伸展因素是它们的决定因素的情况下,它们不必有最大大小。)
伸展因素
控件通常是在没有伸展因素设置的情况下被生成的。当它们被布置到一个布局中时,控件会被根据它们的 QWidget::sizePolicy() 或者它们的最小大小的提示中大的那一个分配给整个空间的一部分。伸展因素是用来根据控件互相的比例来改变它们所被分配的空间。
如果你使用一个 QHBoxLayout 来布置没有伸展参数设置的三个控件,我们就会得到像下面这样的布局:
如果我们给每个控件设置一个伸展因素,它们就会被按比例布置(但是不能小于最小大小的提示),举例来说:
自定义控件的布局
当你创建自己的控件类时,也应该传递它的布局属性。如果这个控件有一个 QLayout,这样的话就已经被处理了。如果这个控件不包括任何子控件,或者使用自定义布局,需要重新实现下面这些 QWidget 的成员函数:
- QWidget::sizeHint() 返回控件的优先选用的大小。
- QWidget::minimumSizeHint() 返回控件所能有的最小大小。
- QWidget::setSizePolicy() 指定控件所需要的空间。
只要大小提示、最小大小提示或者大小策略发生改变,都要调用 QWidget::updateGeometry()。这会引起布局的重新计算。对 updateGeometry() 的多重调用只会引起一次重新计算。
[扩展] Qt 布局学习资料
下面分析我在学习过程中看到的靠谱文章,学习Qt的布局,这几篇文章就足够入门了。
Qt 的官方文档:https://doc.qt.io/qt-5/layout.html.
参考:
相关文章
- Qt之水平/垂直布局(QBoxLayout、QHBoxLayout、QVBoxLayout)
- Qt之自定义布局管理器(QBorderLayout)
- Qt之自定义布局管理器(QFlowLayout)
- 【Qt开发】QT4 升级到 QT5 改动
- 【Qt开发】在QLabel已经显示背景图片后绘制图形注意事项
- qt release版本自动拷贝依赖库
- QT python 界面布局
- QT 一个button的中间布局
- QT python qt designer exe 路径
- qt 获取登录界面账号和密码
- PyQt(Python+Qt)学习随笔:QListWidget的addItems增加多项的方法
- 第九章、Qt Designer可视化设计界面布局组件介绍
- PyQt(Python+Qt)学习随笔:布局控件layout的layoutSizeConstraint属性
- PyQt(Python+Qt)学习随笔:布局控件layout的LeftMargin等contentsMargins属性
- 第15.11节 PyQt(Python+Qt)入门学习:Qt Designer(设计师)组件Property Editor(属性编辑)界面中主窗口QMainWindow类相关属性详解
- 11.QT-布局管理器(Box,Grid,Form,Stacked)
- Use Qt in Debian for OpenCASCADE
- qt计算两个日期之间的差距天数
- 【QT】Qtcreator常用快捷键