1.存在的问题
目前的GUI开发方式:绝对定位
直接在像素级指定各个组件的位置和大小
void QWidget::move(int x, int y)
void QWidget::resize(int w, int h);
问题:组件的位置和大小无法自适应父窗口的变化
2.解决方案:布局管理器
提供相关的类对界面组件进行布局管理
能够自动排列窗口中的界面组件
窗口变化后自动更新界面组件的大小
QLayout是Qt中布局管理器的抽象基类
通过继承QLayout实现了功能各异且互补的布局管理器
Qt中可以根据需要自定义布局管理器
布局管理器不是界面部件,而是界面部件的定位策略
QBoxLayout嵌套实例
void Widget::testVHBoxLayout()
{
QHBoxLayout* hLayout1 = new QHBoxLayout();
QHBoxLayout* hLayout2 = new QHBoxLayout();
QVBoxLayout* vLayout = new QVBoxLayout();
TestBtn1.setText("Test Button 1");
TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
TestBtn1.setMinimumSize(160, 30);
TestBtn2.setText("Test Button 2");
TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
TestBtn2.setMinimumSize(160, 30);
hLayout1->setSpacing(10);
hLayout1->addWidget(&TestBtn1);
hLayout1->addWidget(&TestBtn2);
TestBtn3.setText("Test Button 3");
TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
TestBtn3.setMinimumSize(160, 30);
TestBtn4.setText("Test Button 4");
TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
TestBtn4.setMinimumSize(160, 30);
hLayout2->setSpacing(10);
hLayout2->addWidget(&TestBtn3);
hLayout2->addWidget(&TestBtn4);
vLayout->setSpacing(10);
vLayout->addLayout(hLayout1);
vLayout->addLayout(hLayout2);
setLayout(vLayout);
}
3.布局管理器(2)
布局管理器中的比例系数:
默认情况下以等比例的方式更新组件的大小
可以自定义组件大小更新时的比例系数
QBoxLayout中的比例系数设置:
void setStretch(int index, int stretch)
bool setStretchFactor(QWidget* widget, int stretch)
bool setStretchFactor(QLayout* layout, int stretch)
注意:组件的初始大小是独立于布局管理器设置的,因此不能保证组件的大小始终符合比例系数的设置!
QGridLayout布局管理器
以网格(二维)的方式管理界面组件
布局管理器的嵌套:
QGridLayout支持嵌套其他布局管理器成为其管理对象
void Widget::testGridLayout1()
{
QGridLayout* layout = new QGridLayout();
TestBtn1.setText("Test Button 1");
TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
TestBtn1.setMinimumSize(160, 30);
TestBtn2.setText("Test Button 2");
TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
TestBtn2.setMinimumSize(160, 30);
TestBtn3.setText("Test Button 3");
TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
TestBtn3.setMinimumSize(160, 30);
TestBtn4.setText("Test Button 4");
TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
TestBtn4.setMinimumSize(160, 30);
layout->setSpacing(10);
layout->addWidget(&TestBtn1, 0, 0);
layout->addWidget(&TestBtn2, 0, 1);
layout->addWidget(&TestBtn3, 1, 0);
layout->addWidget(&TestBtn4, 1, 1);
layout->setRowStretch(0, 1);
layout->setRowStretch(1, 3);
layout->setColumnStretch(0, 1);
layout->setColumnStretch(1, 3);
setLayout(layout);
}
QFormLayout布局管理器
以表单(Form)的方式管理界面组件
表单布局中的标签和组件是相互对应的关系
Widget::Widget(QWidget *parent) : QWidget(parent, Qt::WindowCloseButtonHint)
{
QLineEdit* nameEdit = new QLineEdit();
QLineEdit* mailEdit = new QLineEdit();
QLineEdit* addrEdit = new QLineEdit();
QFormLayout* layout = new QFormLayout();
layout->addRow("Name:", nameEdit);
layout->addRow("Email:", mailEdit);
layout->addRow("Address:", addrEdit);
layout->setRowWrapPolicy(QFormLayout::WrapLongRows);
//layout->setLabelAlignment(Qt::AlignRight);
layout->setSpacing(10);
setLayout(layout);
setWindowTitle("FTP");
}
布局管理器的嵌套:
栈式布局管理器(QStackedLayout)
所有组件在垂直于屏幕的方向上别管理
每次只有一个组件会显示在屏幕上
只有最顶层的组件会被最终显示
栈式布局管理器的特点:
组件大小一致且充满父组件的显示区
不能直接嵌套其他布局管理器
能够自由切换需要显示的组件
每次能且仅能显示一个组件
QStackedLayout的用法概要:
·int addWidget(QWidget* widget);
QWidget* currentWidget(); //返回栈式布局管理器最顶层的组件
void setCurrentIndex(int index); //设置初始显示的组件
int currentIndex();
计时器(QTimer)的概念:
计时器是用于每隔一定的时间触发一个消息
计时器消息最终会转化为函数调用
宏观上:
计时器在每个时间间隔会调用指定的函数
计时器(QTimer)的使用方法:
1.编写计时器消息处理函数
2.在程序中创建计时器对象
3.连接计时器消息和消息处理函数
4.设置计时器时间间隔并启动计时