Qt-5种布局控件详解
實(shí)際開發(fā)中,一個(gè)界面上可能包含十幾個(gè)控件,手動調(diào)整它們的位置既費(fèi)時(shí)又費(fèi)力。作為一款成熟的 GUI 框架,Qt 提供了很多擺放控件的輔助工具(又稱布局管理器或者布局控件),它們可以完成兩件事:
- 自動調(diào)整控件的位置,包括控件之間的間距、對齊等;
- 當(dāng)用戶調(diào)整窗口大小時(shí),位于布局管理器內(nèi)的控件也會隨之調(diào)整大小,從而保持整個(gè)界面的美觀。
總之借助布局管理器,我們無需再逐個(gè)調(diào)整控件的位置和大小,可以將更多的精力放在軟件功能的實(shí)現(xiàn)上。
Qt 共提供了 5 種布局管理器,每種布局管理器對應(yīng)一個(gè)類,分別是 QVBoxLayout(垂直布局)、QHBoxLayout(水平布局)、QGridLayout(網(wǎng)格布局)、QFormLayout(表單布局)和 QStackedLayout(分組布局),它們的繼承關(guān)系如下圖所示:
?
圖 1 各個(gè)布局管理類的繼承關(guān)系
QVBoxLayout垂直布局
垂直布局指的是將所有控件從上到下(或者從下到上)依次擺放,例如:
?
圖 2 QVBoxLayout垂直布局
圖 2 展示了 4 個(gè) QPushButton 按鈕利用 QVBoxLayout 垂直布局的效果。實(shí)際場景中,QVBoxLayout 中還可以放置其它控件,比如 QLabel 文本框、QLineEdit 單行輸入框等。
程序中使用 QVBoxLayout 布局控件,需提前引入<QVBoxLayout>頭文件。每個(gè) QVBoxLayout 控件本質(zhì)都是 QVBoxLayout 類的實(shí)例對象,該類提供了兩個(gè)構(gòu)造函數(shù),分別是:
創(chuàng)建 QVBoxLayout 控件的同時(shí)可以指定父窗口,那么它將作為父窗口中管理其它控件的工具;也可以暫時(shí)不指定父窗口,待全部設(shè)置完畢后再將其添加到某個(gè)窗口中。
QVBoxLayout 類沒有新增任何成員方法,它只能使用從父類繼承的成員方法,下表給大家羅列了常用的一些:
?
| void QBoxLayout::addWidget(QWidget *widget, int stretch = 0, Qt::Alignment alignment = Qt::Alignment()) | 向布局管理器中添加指定的 widget 控件。 默認(rèn)情況下,stretch 拉伸系數(shù)為 0,表示 widget 控件的尺寸為默認(rèn)值;alignment 是一個(gè)枚舉類型參數(shù),默認(rèn)值也是 0,表示該控件會填滿占用的整個(gè)空間。 |
| void QBoxLayout::addStretch(int stretch = 0) | 添加一個(gè)空白行,整個(gè)窗口中除了控件占用的區(qū)域外,其它區(qū)域可以由多個(gè)(≥0)空白行分?jǐn)?#xff0c;分?jǐn)偙壤∮嘤诟鱾€(gè)空白行設(shè)置的 stretch 參數(shù)的值。 strech 參數(shù)的默認(rèn)值為 0,表示當(dāng)窗口很小時(shí),空白行可以不占據(jù)窗口空間。當(dāng)窗口中包含多個(gè) strech 值為 0 的空白行時(shí),它們會平分窗口中的空白區(qū)域。 |
| void QBoxLayout::addSpacing(int size) | 添加一個(gè) size 大小的固定間距。 |
| void QLayout::setMargin(int margin) | 設(shè)置布局管理器中所有控件的外邊距,上、下、左、右外邊距的大小都為 margin。默認(rèn)情況下,所有方向的外邊距為 11 px。 |
| void QLayout::setContentsMargins(int left, int top, int right, int bottom) | 設(shè)置布局管理器中所有控件的外邊距,和 setMargin() 的區(qū)別是,此方法可以自定義上、下、左、右外邊距的值。 |
| void QBoxLayout::setDirection(Direction direction) | 設(shè)置布局管理器中控件的布局方向,Direction 是一個(gè)枚舉類型,對于 QVBoxLayout 布局管理器,direction 參數(shù)的值通常選擇?QBoxLayout::TopToBottom(從上到下依次擺放)或者?QBoxLayout::BottomToTop(從下到上依次擺放)。 |
| bool QBoxLayout::setStretchFactor(QWidget *widget, int stretch) | 設(shè)置布局管理器中某個(gè)控件的拉伸系數(shù)。 |
| bool QBoxLayout::setStretchFactor(QLayout *layout, int stretch) | 布局管理器內(nèi)部可以再放置一個(gè)布局管理器,該方法用來設(shè)置內(nèi)部某個(gè)布局管理器的拉伸系數(shù)。 |
舉個(gè)簡單的例子:
程序中做了以下幾個(gè)操作:
- 通過調(diào)用 setDirection() 方法,將添加到 QVBoxLayout 管理器中的所有控件(包括空白行)按照從下到上的順序依次擺放。舉個(gè)例子,由于 lab1 文本框是第二個(gè)添加到管理器中的,因此在最終顯示的界面中,lab1 位于倒數(shù)第二的位置。
- 通過調(diào)用 addStrech() 方法,向管理器中先后添加了兩個(gè)空白行,它們的伸縮系數(shù)分別為 2 和 3,因此 widget 窗口中的空白區(qū)域會平均分為 5 份,一個(gè)空白行占?3 份,另一個(gè)占 2 份。
- 通過調(diào)用 addWidget() 方法,向管理器中先后添加了 3 個(gè)文本框,它們的拉伸系數(shù)比為 1:2:3,所以當(dāng)我們拉伸 widget 窗口時(shí),三個(gè)文本框的大小(寬度)呈現(xiàn) 1:2:3 的關(guān)系。
- 通過調(diào)用 setLayout() 方法,成功地將?layout 布局管理器添加到了 widget 窗口中。當(dāng)然,也可以在創(chuàng)建 layout 對象時(shí)指定 widget 作為它的父窗口,兩種方式是完全等價(jià)的。
執(zhí)行結(jié)果為:
圖 3 QVBoxLayout 實(shí)例演示
QHBoxLayout水平布局
水平布局指的是將所有控件從左到右(或者從右到左)依次擺放,例如:
?
圖 4 QHBoxLayout水平布局
使用 QHBoxLayout 水平布局控件,程序中要提前引入<QHBoxLayout>頭文件。QHBoxLayout 和 QVBoxLayout 繼承自同一個(gè)類,它們的用法非常相似,比如 QHBoxLayout 類也提供了兩個(gè)構(gòu)造函數(shù):
QHBoxLayout 類也沒有新添任何成員方法,它只能使用從父類繼承的成員方法。因此,表 1 中羅列的所有成員方法也同樣適用于 QHBoxLayout 對象。
注意,當(dāng) QHBoxLayout 對象調(diào)用表 1 中的 addStretch() 方法時(shí),表示添加一個(gè)空白列。
舉個(gè)簡單的例子:
程序執(zhí)行結(jié)果為:
圖 5 QHBoxLayout水平布局實(shí)例
圖 5 中,最左側(cè)和最右側(cè)各添加了一個(gè)空白列,它們的伸縮比例為 3:2,即它們的寬度比為 3:2。
QGridLayout網(wǎng)格布局
網(wǎng)格布局又稱格柵布局或者表格布局,指的是將一些控件按照行和列排列在窗口上,例如:
?
圖 6 QGridLayout網(wǎng)格布局
QGridLayout 的行標(biāo)和列標(biāo)都從 0 開始,例如圖 6 中 one 按鈕的位置為 (0, 0),Four 按鈕的位置為 (2, 0)。我們可以隨意指定 QGridLayout 的行數(shù)和列數(shù),各個(gè)控件可以隨意擺放,必要時(shí)某些位置可以空著不用。
使用 QGridLayout 網(wǎng)格控件,程序中需引入<QGridLayout>頭文件。每個(gè) QGridLayout 控件都是 QGridLayout 類的一個(gè)實(shí)例對象,該類提供了兩個(gè)構(gòu)造函數(shù),分別是:
QGridLayout 類提供了很多實(shí)用的成員方法,常用的如下表所示:
| int QGridLayout::rowCount() const | 獲取網(wǎng)格的行數(shù)。 |
| int QGridLayout::columnCount() const | 獲取網(wǎng)格的列數(shù)。 |
| void QGridLayout::addWidget(QWidget *widget, int row, int column, Qt::Alignment alignment = Qt::Alignment()) | 將 widget 控件添加到網(wǎng)格中的?(row,column) 位置處,并且可以自定義該控件的對齊方式。 |
| void QGridLayout::addWidget(QWidget *widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = Qt::Alignment()) | 將 widget 控件從 (fromRow, fromColumn)?位置開始,跨 rowSpan 行和 ColumnSpan 列添加到網(wǎng)格中,并且可以自定義該控件的對齊方式。 |
| void QGridLayout::addLayout(QLayout *layout, int row, int column, Qt::Alignment alignment = Qt::Alignment()) | 向網(wǎng)格中的 (row, column) 位置處添加 layout 布局管理器。 |
| void QGridLayout::addLayout(QLayout *layout, int row, int column, int rowSpan, int columnSpan, Qt::Alignment alignment = Qt::Alignment()) | 將 layout 布局管理器從??(row, column) 位置開始,跨 rowSpan 行和 ColumnSpan 列添加到網(wǎng)格中,并且可以自定義該布局控件的對齊方式。 |
| void QGridLayout::setColumnStretch(int column, int stretch) | 給指定的第 column 列設(shè)置伸縮系數(shù)。 |
| void QGridLayout::setRowStretch(int row, int stretch) | 給指定的第 row 行設(shè)置伸縮系數(shù)。 |
| void QGridLayout::setColumnMinimumWidth(int column, int minSize) | 設(shè)置第 column 列的最小寬度。 |
| void QGridLayout::setRowMinimumHeight(int row, int minSize) | 設(shè)置第 row 行的最小寬度。 |
舉個(gè)簡單的例子:
程序運(yùn)行結(jié)果為:
圖 7 QGridLayout網(wǎng)格布局實(shí)例
圖 7 中,文本框控件從 (1,0) 位置開始,占據(jù)了 3 行 3 列的表格空間。
QFormLayout表單布局
Qt 提供了很多種輸入框控件,包括 QLineEdit 單行輸入框、QTextEdit 多行輸入框等。通常情況下,每個(gè)輸入框的旁邊都會附帶一些文字(又稱標(biāo)簽),用來提示用戶需要輸入的信息。例如,圖 8 中第一個(gè)輸入框的標(biāo)簽為 "Name",提示用戶填寫自己的姓名。
?
圖 8 QFromLayout表單布局
生成圖 8 這樣的界面,實(shí)現(xiàn)的方法有很多,例如:
第 1 種方法最大的弊端在于,各個(gè)控件的尺寸都是固定的,不會隨著父窗口尺寸的改變而改變。第 2、3、4 種方法都是借助布局控件實(shí)現(xiàn)的,各個(gè)控件的尺寸可以自動調(diào)整,但前兩種方法需要手動設(shè)置每一列的 strech 拉伸系數(shù),而第 4 種方式不需要。總之對于生成類似圖 8 這樣的表單窗口,建議大家使用 QFormLayout 控件,因?yàn)槭褂?QFormLayout 編寫的代碼量最少,開發(fā)效率最高。?
QFormLayout 可以容納很多個(gè)輸入框以及對應(yīng)的標(biāo)簽,并將它們從上到下依次排列在界面上(如圖 8 所示)。大多數(shù)情況下,QFormLayout 底層是用 QGridLayout 網(wǎng)格布局管理器實(shí)現(xiàn)的,和后者不同的是,QFormLayout 只包含 2 列(不限制行數(shù)),且第一列放置標(biāo)簽,第二列放置輸入框。
使用 QFormLayout 布局控件之前,程序中應(yīng)引入<QFormLayout>頭文件。每一個(gè)表單布局控件都是 QFormLayout 類的一個(gè)實(shí)例對象,該類僅提供了一個(gè)構(gòu)造函數(shù):
- QFormLayout(QWidget *parent = Q_NULLPTR)
下表給大家羅列了操作 QFormLayout 對象常用的一些成員方法:
?
| void QFormLayout::addRow(QWidget *label, QWidget *field) | 將指定的 field 控件和存儲標(biāo)簽的?label 控件添加到表單控件中的末尾。? |
| void QFormLayout::addRow(const QString &labelText, QWidget *field) | 將指定的 field 控件和 labelText 標(biāo)簽添加到表單控件的末尾。 |
| void QFormLayout::insertRow(int row, const QString &labelText, QWidget *field) | 將指定的 field 控件和 labelText 標(biāo)簽插入到表單控件中指定行的位置。 |
| void QFormLayout::removeRow(int row) | 刪除表單控件中的指定行。 |
| void QFormLayout::removeRow(QWidget *widget) | 刪除表單控件中 widget 控件所在的行。 |
| void setRowWrapPolicy(RowWrapPolicy policy) | 設(shè)置標(biāo)簽的顯示格式,默認(rèn)標(biāo)簽位于控件的左側(cè)。 RowWrapPolicy 是 QFormLayout 中定義的枚舉類型,該類型包含 3 個(gè)值:
|
| void QFormLayout::setSpacing(int spacing) | 將行間距和列間距設(shè)置為 spacing。 |
舉個(gè)簡單的例子:
程序運(yùn)行結(jié)果為:
圖 9 QFormLayout表單布局實(shí)例
QStackedLayout分組布局
QStackedLayout 布局管理器可以容納多個(gè)控件或者窗口,但每次只顯示其中的一個(gè)。
舉個(gè)簡單的例子,下圖中的界面就使用了 QStackedLayout 布局管理器:
圖 10 QStackedLayout布局管理器
整個(gè)窗口被一分為二,左側(cè)是 QListWidget 列表控件,右側(cè)是 QStackedLayout 布局管理器。QStackedLayout 中包含 QPushButonn、QLabel 和 QLineEdit 這 3 個(gè)控件,但每次只能 3 個(gè)控件中的一個(gè)。
QStackedLayout 自身無法切換當(dāng)前顯示的控件或窗口,實(shí)際應(yīng)用時(shí)通常和 QListWidget 或者 QComboBox 搭配使用。
使用 QStackedLayout 布局控件,程序中必須先引入<QStackedLayout>頭文件。 每個(gè) QStackedLayout 控件都是 QStackedLayout 類的一個(gè)實(shí)例對象,該類提供有 3 個(gè)構(gòu)造函數(shù),分別是:
借助第二個(gè)構(gòu)造函數(shù),我們可以將 QStackedLayout 添加到指定的 parent 窗口中;借助第三個(gè)構(gòu)造函數(shù),我們可以將 QStackedLayout 嵌入到指定的?parentLayout 布局控件中
本節(jié)學(xué)習(xí)的 5 種布局控件都可以嵌套使用,例如將 QVBoxLayout 放到 QHBoxLayout 內(nèi)部、將 QGridLayout 放到 QStackedLayout 內(nèi)部等。
下表羅列了操作 QStackedLayout 對象常用的一些成員方法:
| int QStackedLayout::addWidget(QWidget *widget) | 將 widget 控件添加到 QStackedLayout 控件中。 |
| int QStackedLayout::insertWidget(int index, QWidget *widget) | 將 widget 控件插入到 QStackedLayout?控件指定的位置處。 |
| void QStackedLayout::currentChanged(int index) | 切換當(dāng)前顯示的控件時(shí),會觸發(fā)此信號,index 為顯示的新控件的索引。 |
| void QStackedLayout::widgetRemoved(int index) | 移除某個(gè)控件時(shí),會觸發(fā)此信號,index 為被移除控件的索引。 |
| void setCurrentIndex(int index) | 將第 index 個(gè)控件作為要顯示的控件。 |
| void QStackedLayout::setCurrentWidget(QWidget *widget) | 設(shè)置 widget 作為當(dāng)前要實(shí)現(xiàn)的控件。注意,必須保證 widget 存儲在 QStackedLayout 控件中。 |
這里我們以圖 10 所示的窗口為例,實(shí)現(xiàn)代碼如下:
此程序中,我們在 QHBoxLayout 水平布局控件內(nèi)又放置了一個(gè) QStackedLayout 分組布局控件。感興趣的讀者可以編寫程序,測試其它布局控件之間嵌套的效果。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的Qt-5种布局控件详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决: /bin/sh: 1: jav
- 下一篇: Qt-手动布局