1. 程式人生 > >QT之布局管理器(十九)

QT之布局管理器(十九)

QT 布局管理器 水平 垂直

我們在之前的 GUI 開發中都是使用的是絕對定位,何謂絕對定位呢?就是我們直接在像素級指定各個組件的位置和大小。比如我們之前使用的 void QWidget::move(int x, int y);void QWidget::resize(int w, int h);這樣存在的問題就是組件的位置和大小無法自適應父窗口的變化。

我們先來看看絕對定位的代碼和效果是怎樣的?頭文件代碼如下:

#include <QWidget>
#include <QPushButton>

class Widget : public QWidget
{
    Q_OBJECT
private:
    QPushButton TestBtn1;
    QPushButton TestBtn2;
    QPushButton TestBtn3;
    QPushButton TestBtn4;

    void initControl();
public:
    Widget(QWidget *parent = 0);
    ~Widget();
};

具體函數代碼如下:

void Widget::initControl()
{
    TestBtn1.setText("Test Button 1");
    TestBtn1.move(20, 20);
    TestBtn1.resize(160, 30);

    TestBtn2.setText("Test Button 2");
    TestBtn2.move(20, 70);
    TestBtn2.resize(160, 30);

    TestBtn3.setText("Test Button 3");
    TestBtn3.move(20, 120);
    TestBtn3.resize(160, 30);

    TestBtn4.setText("Test Button 4");
    TestBtn4.move(20, 170);
    TestBtn4.resize(160, 30);
}

圖一為構建運行後得到的原始界面,圖二為我們放大後的效果圖:

技術分享圖片 技術分享圖片

圖一 圖二

那麽有什麽解決方法嗎?答案就是布局管理器,它能夠提供相關的類對界面組件進行布局管理。能夠自動排列窗口中的界面組件,窗口變化後自動更新界面組件的大小。

QLayout 是 Qt 中布局管理器的抽象基類,通過繼承 QLayout 實現了功能各異且互補的布局管理器、Qt 中可以根據需要自定義布局管理器。註意:布局管理器不是界面部件,而是界面部件的定位策略!!!

關系如下所示:

技術分享圖片


QBoxLayout 布局管理器 以水平或者垂直的方式管理界面組件,如下:

技術分享圖片技術分享圖片

我們下面來進行一組實驗,我們先來以垂直的方式進行排布,代碼如下:

void Widget::testVBoxLayout()
{
    QVBoxLayout* layout = 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);

    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(20);         // 設置間距為20個像素
    layout->addWidget(&TestBtn1);   // 添加 TestBtn1
    layout->addWidget(&TestBtn2);
    layout->addWidget(&TestBtn3);
    layout->addWidget(&TestBtn4);

    setLayout(layout);
}

圖三為構建運行後得到的原始界面,圖四為我們放大後的效果圖:

技術分享圖片 技術分享圖片

圖三 圖四

我們再試下水平布局,在上面代碼中僅僅只是將 QVBoxLayout 改成 QHBoxLayout,繼續構建運行後效果如下:

技術分享圖片

那麽我們的布局管理器還可以相互嵌套,形成更加復雜的布局方式。布局嵌套幾乎可以完成所有常用的界面布局,我們還可以定義布局類以達到個性化布局的效果。下來我們就做個 QBoxLayout 嵌套示例,如下:

技術分享圖片

代碼如下:

void Widget::testVHBoxLayout()
{
    QHBoxLayout* hLayout1 = new QHBoxLayout();  // 設置水平方向 hLayout1
    QHBoxLayout* hLayout2 = new QHBoxLayout();  // 設置水平方向 hLayout2
    QVBoxLayout* vLayout = new QVBoxLayout();   // 設置垂直方向 vLayout

    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);     // 水平方向添加 TestBtn1
    hLayout1->addWidget(&TestBtn2);     // 水平方向添加 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);       // 豎直方向添加 hLayout1
    vLayout->addLayout(hLayout2);       // 豎直方向添加 hLayout2

    setLayout(vLayout);
}

構建運行效果如下:

技術分享圖片

那麽本次我們學習了布局管理相關的知識。絕對定位的布局方式是無法適應窗口的變化的,在 Qt 中提供了相關的類對界面組件進行布局管理。Qt 預定義了功能各異的且互補的布局管理器,布局管理器能夠相互嵌套形成復雜的布局。在後面我們會接著對 Qt 的布局管理方式進行學習。


以上內容來自狄泰軟件學院的QT教程,歡迎大家一起來學習,可以加我QQ:243343083,一起學習。狄泰技術交流群:199546072

QT之布局管理器(十九)