一文詳解Qt如何優(yōu)雅的進(jìn)行界面布局
1 寫在前面
之前使? Qt 在界?上創(chuàng)建的控件, 都是通過 “絕對定位” 的?式來設(shè)定的。也就是每個(gè)控件所在的位置, 都需要計(jì)算坐標(biāo), 最終通過 setGeometry
或者 move ?式擺放過去。
這種設(shè)定?式其實(shí)并不?便,尤其是界?如果內(nèi)容?較多, 不好計(jì)算。?且?個(gè)窗???往往是可以調(diào)整的, 按照絕對定位的?式, 也?法?適應(yīng)窗???。因此 Qt 引? 布局管理器 (Layout) 機(jī)制, 來解決上述問題。
2 垂直布局
使? QVBoxLayout
表?垂直的布局管理器,V 是 vertical 的縮寫。
核?屬性:
屬性 | 說明 |
---|---|
layoutLeftMargin | 左側(cè)邊距 |
layoutRightMargin | 右側(cè)邊距 |
layoutTopMargin | 上?邊距 |
layoutBottomMargin | 下?邊距 |
layoutSpacing | 相鄰元素之間的間距 |
Layout 只是?于界?布局, 并沒有提供信號(hào)。
代碼示例:
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); QPushButton* btn1 = new QPushButton("按鈕1"); QPushButton* btn2 = new QPushButton("按鈕2"); QPushButton* btn3 = new QPushButton("按鈕3"); // 創(chuàng)建布局管理器, 并且把按鈕添加進(jìn)去 // 如果創(chuàng)建的時(shí)候指定?元素為 this, 則后?不需要 setLayout ?法 QVBoxLayout* layout = new QVBoxLayout(); layout->addWidget(btn1); layout->addWidget(btn2); layout->addWidget(btn3); // 把布局管理器設(shè)置到 widget 中 this->setLayout(layout); }
驗(yàn)證結(jié)果:
使用代碼的方式時(shí)我們拖拽窗口時(shí),按鈕的位置也會(huì)隨著窗口的調(diào)整而改變。
我們還可以使用圖形化界面的方式來進(jìn)行垂直布局:
但是注意使用圖形化界面的方式時(shí)我們拖拽窗口,按鈕的位置不會(huì)隨著窗口的調(diào)整而改變。
3 水平布局
使? QHBoxLayout
表?垂直的布局管理器,H 是 horizontal 的縮寫。
核?屬性 (和 QVBoxLayout 屬性是?致的)
屬性 | 說明 |
---|---|
layoutLeftMargin | 左側(cè)邊距 |
layoutRightMargin | 右側(cè)邊距 |
layoutTopMargin | 上?邊距 |
layoutBottomMargin | 下?邊距 |
layoutSpacing | 相鄰元素之間的間距 |
代碼?例:
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); QPushButton* btn1 = new QPushButton("按鈕1"); QPushButton* btn2 = new QPushButton("按鈕2"); QPushButton* btn3 = new QPushButton("按鈕3"); // 創(chuàng)建布局管理器 QHBoxLayout* layout = new QHBoxLayout(); layout->addWidget(btn1); layout->addWidget(btn2); layout->addWidget(btn3); // 設(shè)置 layout 到 widget 上 this->setLayout(layout); }
結(jié)果驗(yàn)證:
同理我們也可以使用圖形化界面的方式來創(chuàng)建水平布局。這里就不再演示了。
4 網(wǎng)格布局
Qt 中還提供了 QGridLayout
?來實(shí)現(xiàn)?格布局的效果,可以達(dá)到 M * N 的這種?格的效果。
核?屬性:整體和 QVBoxLayout
以及 QHBoxLayout
相似,但是設(shè)置 spacing
的時(shí)候是按照垂直?平兩個(gè)?向來設(shè)置的。
屬性 | 說明 |
---|---|
layoutLeftMargin | 左側(cè)邊距 |
layoutRightMargin | 右側(cè)邊距 |
layoutTopMargin | 上?邊距 |
layoutBottomMargin | 下?邊距 |
layoutHorizontalSpacing | 相鄰元素之間?平?向的間距 |
layoutVerticalSpacing | 相鄰元素之間垂直?向的間距 |
layoutRowStretch | ??向的拉伸系數(shù) |
layoutColumnStretch | 列?向的拉伸系數(shù) |
代碼?例:
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); // 創(chuàng)建 4 個(gè)按鈕 QPushButton* btn1 = new QPushButton("按鈕1"); QPushButton* btn2 = new QPushButton("按鈕2"); QPushButton* btn3 = new QPushButton("按鈕3"); QPushButton* btn4 = new QPushButton("按鈕4"); // 創(chuàng)建?格布局管理器, 并且添加元素 QGridLayout* layout = new QGridLayout(); layout->addWidget(btn1, 0, 0); layout->addWidget(btn2, 0, 2); layout->addWidget(btn3, 1, 1); layout->addWidget(btn4, 1, 3); // 設(shè)置 layout 到窗?中. this->setLayout(layout); }
結(jié)果驗(yàn)證:
我們再來看看使用下面的代碼會(huì)出現(xiàn)什么情況:
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); // 創(chuàng)建 4 個(gè)按鈕 QPushButton* btn1 = new QPushButton("按鈕1"); QPushButton* btn2 = new QPushButton("按鈕2"); QPushButton* btn3 = new QPushButton("按鈕3"); QPushButton* btn4 = new QPushButton("按鈕4"); // 創(chuàng)建?格布局管理器, 并且添加元素 QGridLayout* layout = new QGridLayout(); layout->addWidget(btn1, 0, 0); layout->addWidget(btn2, 1, 0); layout->addWidget(btn3, 2, 0); layout->addWidget(btn4, 5, 0); // 設(shè)置 layout 到窗?中. this->setLayout(layout); }
結(jié)果驗(yàn)證:
此處也要注意, 設(shè)置?和列的時(shí)候, 如果設(shè)置的是?個(gè)很?的值, 但是這個(gè)值和上?個(gè)值之間并沒有其他的元素, 那么并不會(huì)在中間騰出額外的空間。
代碼?例: 設(shè)置 QGridLayout 中元素的???例
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); // 創(chuàng)建 6 個(gè)按鈕 QPushButton* btn1 = new QPushButton("按鈕1"); QPushButton* btn2 = new QPushButton("按鈕2"); QPushButton* btn3 = new QPushButton("按鈕3"); QPushButton* btn4 = new QPushButton("按鈕4"); QPushButton* btn5 = new QPushButton("按鈕5"); QPushButton* btn6 = new QPushButton("按鈕6"); // 創(chuàng)建?格布局管理器, 并且添加元素 QGridLayout* layout = new QGridLayout(); layout->addWidget(btn1, 0, 0); layout->addWidget(btn2, 0, 1); layout->addWidget(btn3, 0, 2); layout->addWidget(btn4, 1, 0); layout->addWidget(btn5, 1, 1); layout->addWidget(btn6, 1, 2); // 設(shè)置拉伸?例,設(shè)置為0的話為默認(rèn)大小 // 第 0 列拉伸?例設(shè)為 3; layout->setColumnStretch(0, 3); // 第 1 列拉伸?例設(shè)為 2, layout->setColumnStretch(1, 2); // 第 2 列拉伸?例設(shè)為 1 layout->setColumnStretch(2, 1); // 設(shè)置 layout 到窗?中. this->setLayout(layout); }
結(jié)果驗(yàn)證:
另外, QGridLayout
也提供了 setRowStretch
設(shè)置?之間的拉伸系數(shù)。上述案例中, 直接設(shè)置 setRowStretch
效果不明顯, 因?yàn)槊總€(gè)按鈕的?度是固定的,需要把按鈕的垂直?向的 sizePolicy
屬性設(shè)置為 QSizePolicy::Expanding
盡可能填充滿布局管理器, 才能看到效果。
代碼?例: 設(shè)置垂直?向的拉伸系數(shù)。
使? setSizePolicy
設(shè)置按鈕的尺?策略,可選的值如下:
- QSizePolicy::Ignored : 忽略控件的尺?,不對布局產(chǎn)?影響。
- QSizePolicy::Minimum : 控件的最?尺?為固定值,布局時(shí)不會(huì)超過該值。
- QSizePolicy::Maximum : 控件的最?尺?為固定值,布局時(shí)不會(huì)?于該值。
- QSizePolicy::Preferred : 控件的理想尺?為固定值,布局時(shí)會(huì)盡量接近該值。
- QSizePolicy::Expanding : 控件的尺?可以根據(jù)空間調(diào)整,盡可能占據(jù)更多空間。
- QSizePolicy::Shrinking : 控件的尺?可以根據(jù)空間調(diào)整,盡可能縮?以適應(yīng)空間。
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); // 創(chuàng)建 6 個(gè)按鈕 QPushButton* btn1 = new QPushButton("按鈕1"); QPushButton* btn2 = new QPushButton("按鈕2"); QPushButton* btn3 = new QPushButton("按鈕3"); QPushButton* btn4 = new QPushButton("按鈕4"); QPushButton* btn5 = new QPushButton("按鈕5"); QPushButton* btn6 = new QPushButton("按鈕6"); // 設(shè)置按鈕的 sizePolicy, 此時(shí)按鈕的?平?向和垂直?向都會(huì)盡量舒展開 btn1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); btn2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); btn3->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); btn4->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); btn5->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); btn6->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); // 創(chuàng)建?格布局管理器, 并且添加元素 QGridLayout* layout = new QGridLayout(); layout->addWidget(btn1, 0, 0); layout->addWidget(btn2, 0, 1); layout->addWidget(btn3, 1, 0); layout->addWidget(btn4, 1, 1); layout->addWidget(btn5, 2, 0); layout->addWidget(btn6, 2, 1); // 設(shè)置拉伸?例 // 第 0 ?拉伸?例設(shè)為 1; layout->setRowStretch(0, 1); // 第 1 ?拉伸?例設(shè)為 0, 即為固定??, 不參與拉伸 layout->setRowStretch(1, 0); // 第 2 ?拉伸?例設(shè)為 2, 即為第 2 ?的寬度是第 0 ?的 2 倍 layout->setRowStretch(2, 2); // 設(shè)置 layout 到窗?中. this->setLayout(layout); }
結(jié)果驗(yàn)證:
5 表單布局
除了上述的布局管理器之外, Qt 還提供了 QFormLayout
, 屬于是 QGridLayout
的特殊情況, 專??于實(shí)現(xiàn)兩列表單的布局。這種表單布局多?于讓??填寫信息的場景,左側(cè)列為提?, 右側(cè)列為輸?框。
代碼示例:
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); // 創(chuàng)建 layout QFormLayout* layout = new QFormLayout(); this->setLayout(layout); // 創(chuàng)建三個(gè) label QLabel* label1 = new QLabel("姓名"); QLabel* label2 = new QLabel("年齡"); QLabel* label3 = new QLabel("電話"); // 創(chuàng)建三個(gè) lineEdit QLineEdit* lineEdit1 = new QLineEdit(); QLineEdit* lineEdit2 = new QLineEdit(); QLineEdit* lineEdit3 = new QLineEdit(); // 創(chuàng)建?個(gè)提交按鈕 QPushButton* btn = new QPushButton("提交"); // 把上述元素添加到 layout 中 layout->addRow(label1, lineEdit1); layout->addRow(label2, lineEdit2); layout->addRow(label3, lineEdit3); layout->addRow(NULL, btn); }
結(jié)果驗(yàn)證:
以上就是一文詳解Qt如何優(yōu)雅的進(jìn)行界面布局的詳細(xì)內(nèi)容,更多關(guān)于Qt界面布局的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于VC中使用ForceInclude來強(qiáng)制包含stdafx.h的解決方法
本篇文章是對VC中使用ForceInclude來強(qiáng)制包含stdafx.h的解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C/C++高精度運(yùn)算(大整數(shù)運(yùn)算)詳細(xì)講解
高精度算法的本質(zhì)是把大數(shù)拆成若干固定長度的塊,然后對每一塊進(jìn)行相應(yīng)的運(yùn)算,下面這篇文章主要給大家介紹了關(guān)于C/C++高精度運(yùn)算(大整數(shù)運(yùn)算)的相關(guān)資料,需要的朋友可以參考下2022-11-11C語言用循環(huán)單鏈表實(shí)現(xiàn)約瑟夫環(huán)
這篇文章主要為大家詳細(xì)介紹了C語言用循環(huán)單鏈表實(shí)現(xiàn)約瑟夫環(huán),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10詳解C語言中scanf函數(shù)使用的一些注意點(diǎn)
這篇文章主要介紹了C語言中scanf函數(shù)使用的一些注意點(diǎn),scanf函數(shù)的使用是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-04-04一起來學(xué)習(xí)C語言的字符串轉(zhuǎn)換函數(shù)
這篇文章主要為大家詳細(xì)介紹了C語言的字符串轉(zhuǎn)換函數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02