您的当前位置:首页正文

Qt布局管理器

2024-11-13 来源:个人技术集锦

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.设置计时器时间间隔并启动计时

Top