Qt窗口部件与布局之二:布局管理
第3章講述了一些窗口部件,當(dāng)時往界面上拖放部件時都是隨意放置的,這對于學(xué)習(xí)部件的使用沒有太大的影響,但是,對于一個完善的軟件,布局管理卻是必不可少的。 無論是想要界面中部件有一個很整齊的排列,還是想要界面能適應(yīng)窗口的大小變化,都 要進(jìn)行布局管理。Qt中主要提供了 QLayout 類及其子類來作為布局管理器,它們可以實(shí)現(xiàn)常用的布局管理功能,QLayout及其子類的關(guān)系如下圖所示。
一、布局管理系統(tǒng)
Qt的布局管理系統(tǒng)提供了簡單而強(qiáng)大的機(jī)制來自動排列一個窗口中的部件,確保它們有效地使用空間。Qt包含了一組布局管理類來描述怎樣在應(yīng)用程序的用戶界面中對部件進(jìn)行布局,比如QLayout的幾個子類,這里將它們稱作布局管理器。所有 QWidget 類的子類的實(shí)例(對象)都可以使用布局管理器來管理位于其中的子部件, QWidget::setLayOut()函數(shù)可以在一個部件上應(yīng)用布局管理器。一旦一個部件上設(shè)置了布局管理器,那么它會完成以下幾種任務(wù):
- 定位子部件;
- 感知窗口默認(rèn)大小;
- 感知窗口最小大小;
- 改變大小處理;
- 當(dāng)內(nèi)容改變時自動更新:
- 字體大小,文本或子部件的其他內(nèi)容隨之改變;
- 隱藏或顯示子部件;
- 移除一個子部件。
1.1 布局管理器
QLayout類是布局管理器的基類,是一個抽象基類,繼承自 QObject 和 QLayoutItem 類,而 QLayoutltem 類提供了 一個供 QLayout 操作的抽象項(xiàng)目。QLayout 和 QLayoutItem 都是在設(shè)計(jì)自己的布局管理器時才使用的,一般只需要使用 QLayout 的幾個子類就可以了,分別是 QBoxLayout(基本布局管理器)、QGridLayout(柵格布局管理器)、QFormLayout(表單布局管理器)和QStackedLayout(棧布局管理器)。
下面先來看一個例子。新建 QtGui 應(yīng)用,項(xiàng)目名稱為 myLayout,類名 MyWidget,基類選擇 QWidget。然后打開 mywidget. ui 文件,在設(shè)計(jì)模式中向界面拖人一個字體選擇框 Font Combo Box 和文本編輯器 Text Edit 部件。然后單擊主界面并按下 Ctrl + L 快捷鍵,或者單擊設(shè)計(jì)器上邊欄中的“垂直布局”圖標(biāo)來對主界面進(jìn)行垂直布局管理。也可以在主界面上右擊,在彈出的菜單中選擇“布局→垂直布局”,這樣便設(shè)置了頂層布局管理器,可以看到兩個部件已經(jīng)填滿了整個界面。這時運(yùn)行程序,然后拉伸窗口,兩個部件會隨著窗口的大小變化而變化,如下圖所示。這就是布局管理器在起作用。
1. 基本布局管理器(QBoxLayout)
基本布局管理器 QBoxLayout 類可以使子部件在水平方向或者垂直方向排成一列,將所有的空間分成一行盒子,然后將每個部件放入一個盒子中。它有兩個子類 QHBoxLayont 水平布局管理器和 QVBoxLayout 垂直布局管理器。單擊主界面,查看它的屬性欄,最后面的部分是其使用的布局管理器的屬性,如下圖所示。
下面打破已有布局,使用代碼實(shí)現(xiàn)水平布局。在界面上右擊,然后在右鍵菜單中選擇“打破布局”,或者單擊設(shè)計(jì)器上邊欄中的打破布局圖標(biāo)。在 mywidget. cpp 文件中 添加頭文件 #include <QHBoxLayout>,并在 MyWidget 類的構(gòu)造閑數(shù)中添加如下代碼:
QHBoxLayout *layout = new QHBoxLayout; // 新建水平布局管理器 layout->addWidget(ui->fontComboBox); // 向布局管理器中添加部件 layout->addWidget(ui->textEdit); layout->setSpacing(50); // 設(shè)置部件間的間隔 layout->setContentsMargins(0, 0, 50, 100); // 設(shè)置布局管理器到邊界的距離 // 四個參數(shù)順序是左,上,右,下 setLayout(layout); // 將這個布局設(shè)置為MyWidget類的布局這里使用了 addWidget() 函數(shù)向布局管理器的末尾添加部件,還有一個 insertWidget() 函數(shù)可以實(shí)現(xiàn)向指定位置添加部件,它比前者更靈活。
2. 柵格布局管理器(QGridLayout)
柵格布局管理器QGridLaycnit類使得部件在網(wǎng)格中布局,它將所有的空間分隔成一些行和列,行和列的交叉處就形成了單元格,然后將部件放人一個確定的單元格中。下面編寫代碼來使用柵格布局管理器。先往界面上拖放一個 Push Button,然后在 mywidget. cpp 中添加頭文件 #include <QGridLayout>, 再使用/ * * /注釋掉上面添加的關(guān)于水平布局管理器的代碼,最后再添加如下代碼:
QGridLayout *layout = new QGridLayout; // 添加部件,從第0行0列開始,占據(jù)1行2列 layout->addWidget(ui->fontComboBox, 0, 0, 1, 2); // 添加部件,從第0行2列開始,占據(jù)1行1列 layout->addWidget(ui->pushButton, 0, 2, 1, 1); // 添加部件,從第1行0列開始,占據(jù)1行3列 layout->addWidget(ui->textEdit, 1, 0, 1, 3); setLayout(layout);這里主要是設(shè)置了部件在柵格布局管理器中的位罝,將 fontComBox 部件設(shè)置為占據(jù)1行2列,而 pushBimon 部件占據(jù)1行1列,這主要是為了將 fontComBox 部件和 pushBuuon 部件的長度設(shè)置為2: 1。而這樣一來,textEdit部件要想占滿剩下的空間,就要使它的跨度為3列。
這里需要說明,當(dāng)部件加入到一個布局管理器中,然后這個布局管理器再放到一個窗口部件上時,這個布局管理器以及它包含的所有部件都會把該窗口部件自動重新定義為自己的父對象(parent),所以在創(chuàng)建布局管理器和其中的部件時不用指定父部件。
3. 表單布局管理器(QFormLayout)
表單布局管理器 QFormLayout 類用來管理表格的輸入部件及其相關(guān)的標(biāo)簽,將它的子部件分為兩列,左邊是一些標(biāo)簽,右邊是一些輸入部件,比如行編輯器或者數(shù)字選擇框等。其實(shí)如果只是起到這樣的布局作用,那么用QGridLayout就完全可以做到 了,之所以添加QFormLayout類,是因?yàn)樗歇?dú)特的功能。下面看一個例子。
先將前面在MyWidget類的構(gòu)造函數(shù)中自己添加的代碼全部注釋掉,然后進(jìn)入設(shè)計(jì)模式,這里使用另外一種方法來使用布局管理器。從部件欄中找到 Form Layout,將其拖入到界面上,然后雙擊或者在它上面右擊,選擇“添加窗體布局行菜單。然后在彈出的“添加表單布局行”對話框中輸人標(biāo)簽文字“姓名(&N):”,則下面自動填寫了“標(biāo)簽名稱”、“字段類型”和“字段名稱”等,并且設(shè)置了伙伴關(guān)系。這里使用了 QLineEdit 行編輯器,當(dāng)然也可以選擇其他部件。而填寫的標(biāo)簽文字中(&N)要注意括號必須是英語半角的,表明它的加速鍵是Alt + N,設(shè)置伙伴關(guān)系表示當(dāng)按下Alt + N時,光標(biāo)會自動跳轉(zhuǎn)到標(biāo)簽后面對應(yīng)的行編輯器中。按下確定鍵便會在布局管理器中添加一個標(biāo)簽和一個行編輯器。按照這種方法,再添加3行:性別(&S),使用 QComoBox;年齡 (&A),使用QSpinBox;郵箱(&M),使用 QLineEdit。可以按下加速鍵 Alt + N,光標(biāo)就可以定位到“姓名”標(biāo)簽后的行編輯器中。
上面的添加表單行是在設(shè)計(jì)器中完成的,也可以在代碼中使用 addRow() 函數(shù)來完成。表單布局管理器為設(shè)計(jì)填寫表單的窗口提供了方便的功能,其實(shí)還有一些實(shí)用的特性。表單管理器也可以像普通管理器一樣使用,但是,如果不是為了設(shè)計(jì)這樣的表單,一般會使用柵格布局管理器。
4. 綜合設(shè)計(jì)布局管理器)
前面講到了 3 種布局管理器,真正使用時很多時候是將它們綜合起來應(yīng)用的。現(xiàn)在將前面的界面再進(jìn)行設(shè)計(jì):按下Ctrl鍵同時選中界面上的字體選擇框 fontComboBox 和按鈕 pushButton,然后按下Ctrl + H快捷鍵將它們放人一個水平布局管理器中 。然后再從部件欄中拖入一個 Vertical Spacer 垂直分隔符,它們是用來在部件間產(chǎn)生間隔的,將它放在表單布局管理器與水平布局管理器之間。然后單擊主界面,然后按下Ctrl + L快捷鍵,讓整個界面處于一個垂直布局管理器中。這時可以在右上角的對象列表中選擇分隔符Spacer,然后在屬性欄中設(shè)置它的高度為100。這時運(yùn)行程序,效果如下圖所示。
這里綜合使用了表單布局管理器、水平布局管理器和垂直布局管理器,其中垂直布局管理器是頂級布局管理器,因?yàn)樗侵鹘缑娴牟季?#xff0c;其他兩個布局管理器都包含在它里面。如果要使用代碼來實(shí)現(xiàn)將一個子布局管理器放入一個父布局管理器之中,可以使用父布局管理器的 addLayout() 函數(shù)。
1.2 可擴(kuò)展窗口
一個窗口可能有很多選項(xiàng)是擴(kuò)充的,只有在必要的時候才顯示出來,這時就可以使用一個按鈕,用來隱藏或者顯示多余的內(nèi)容,就是所謂的可擴(kuò)展窗口。要實(shí)現(xiàn)可擴(kuò)展窗 口,就要得力于布局管理器的特性,那就是當(dāng)子部件隱藏時,布局管理器自動縮小,當(dāng)子部件重新顯示時,布局管理器再次放大。下面看一個具體的例子。
依然在前面的程序中進(jìn)行更改。首先將界面上 pushBimon 的顯示文本更改為“顯示可擴(kuò)展窗口”,然后在其屬性欄中選中 checkable 選項(xiàng)。然后轉(zhuǎn)到它的 toggled(bool) 信號的槽,更改如下:
// 顯隱窗口按鈕 void MyWidget::on_pushButton_toggled(bool checked) {ui->textEdit->setVisible(checked); // 設(shè)置文本編輯器的顯示和隱藏if(checked)ui->pushButton->setText(tr("隱藏可擴(kuò)展窗口"));elseui->pushButton->setText(tr("顯示可擴(kuò)展窗口")); }使用按鈕的按下與否兩種狀態(tài)來設(shè)置文本編輯器是否顯示,并且相應(yīng)更改按鈕的文本。為了讓文本編輯器在一開始是隱藏的,還要在MyWidget類的構(gòu)造函數(shù)中添加—行代碼:
ui->textEdit->hide(); // 讓文本編輯器隱藏,也可以使用setVisible(false)函數(shù)運(yùn)行程序。可擴(kuò)展窗口隱藏時效果如下圖1所示,可擴(kuò)展窗口顯示時如下圖2所示。也可以參考Qt自帶的示例程序 Extension Dialog,它在 Dialogs 分類中。
1.3 分裂器
分裂器 QSplitter 類提供了一個分裂器部件,和 QBoxLayout 很相似,可以完成布局管理器的功能,但是包含在它里面的部件,默認(rèn)是可以隨著分裂器的大小變化而進(jìn)行相應(yīng)大小變化的。比如一個按鈕放在布局管理器中,它的垂直方向默認(rèn)是不會被拉伸的,但是放到分裂器中就可以被拉伸。還有一個不同就是,布局管理器是繼承自 QObject 類的,而分裂器卻是繼承自 QFrame 類,QFrame 類又是繼承自 QWidget 類,也就是說,分裂器擁有 QWidget 類的特性,它是可見的,而且可以像 QFrame —樣設(shè)置邊框。下面看一個例子。
新建Qt Gui應(yīng)用,項(xiàng)目名稱為mySplitter,類名My Widget,基類選擇QWidget。 建好項(xiàng)目后打開 mywidget. ui 文 件,然后往上面拖人4個 Push Button, 同時選中這4個按鈕然后右擊,選擇 “布局—使用分裂器水平布局”菜單項(xiàng), 將這4個按鈕放到一個分裂器中。將分裂器拉大點(diǎn),并在屬性欄中設(shè)置其 frameShape 為 Box,frameShadow 為 Raised,line Width為5。此時運(yùn)行程序,效果如下圖所示。
二、設(shè)置伙伴
講述表單布局管理器時提到了設(shè)置一個標(biāo)簽和一個部件的伙伴關(guān)系。其實(shí),伙伴 (buddy) 是在 QLabel 類中提出的一個概念。因?yàn)橐粋€標(biāo)簽經(jīng)常用作一個交互式部件的說明,就像在講表單布局管理器時看到的那樣,一個 lineEdit 部件前面有一個標(biāo)簽說明這個 lineEdit 的作用。為了方便定位,QLabel 提供了一個有用的機(jī)制,那就是提供了助記符來設(shè)置鍵盤焦點(diǎn)到對應(yīng)的部件上,這個部件就叫這個 QLabel 的伙伴。其中助記符就是我們所說的加速鍵。使用英文標(biāo)簽時,在字符串的一個字母前面添加“&” 符號,那么就可以指定這個標(biāo)簽的加速鍵是Alt加上這個字母,而對于中文,需要在小括號中指定加速鍵字母。Qt設(shè)計(jì)器中也提供了伙伴設(shè)計(jì)模式,下面看一個例子。
新建Qt Gui應(yīng)用,項(xiàng)目名稱為myBuddy, 類名MyWidget,基類選擇 QWidget。建好項(xiàng)目后打開 mywidget. ui 文件,然后往界面上拖放4個標(biāo)簽 Label,再在標(biāo)簽后面依次放上 PushButton、CheckBox、LineEdit和 SpinBox。然后將 PushButton 前面的標(biāo)簽的文本改為“&Button:”;CheckBox 前面的標(biāo)簽文本改為“C&heckBox:”; LineEdit 前面的標(biāo)簽的文本改為“行編輯器(&L):”;SpinBox前面的標(biāo)簽文本改為“數(shù)字選擇框(&N):”。單擊下設(shè)計(jì)器頂部欄中的“編輯伙伴圖標(biāo)“進(jìn)人伙伴設(shè)計(jì)模式,分別將各個標(biāo)簽與它們后面的部件連起來,如下圖所示。然后按下F3回到正常編輯模式,可以看到所有的&符號都沒有了,只是在字母下面多了一 個橫杠,表示這個標(biāo)簽的加速鍵就是Alt加這個字母。
現(xiàn)在可以運(yùn)行程序,使用加速鍵測試效果。如果要在代碼中設(shè)置伙伴關(guān)系,只需要使用 QLabel 的 setBuddy() 函數(shù)就可以了。對應(yīng)于本小節(jié)內(nèi)容可以在幫助索引中查看 Qt Designer's Buddy Editing Mode 關(guān)鍵字。
三、設(shè)置Tab順序
對于一個應(yīng)用程序,我們有時總希望使用Tab鍵來將焦點(diǎn)從一個部件移動到下一個部件。在設(shè)計(jì)模式,設(shè)計(jì)器提供了Tab鍵的設(shè)置功能。上面程序的設(shè)計(jì)模式中,單擊上邊欄的“編輯Tab順序(Edit Tab Order)”按鈕進(jìn)人編輯Tab鍵順序模式,這時已經(jīng)顯示出了各個部件的Tab鍵順序,只需要單擊這些數(shù)字即可以更改。需要說明,當(dāng)程序啟動時,焦點(diǎn)會在Tab鍵順序?yàn)?的部件上。這里進(jìn)行的設(shè)置等價于在MyWidget類的構(gòu)造函數(shù)中使用如下代碼:
setTabOrder(ui->lineEdit, ui->spinBox); //lineEdit,在spinBox前面setTabOrder(ui->spinBox, ui->pushButton); //spinBox,在pushButton前面setTabOrder(ui->pushButton, ui->checkBox); //pushButton,在checkBox前面關(guān)于在設(shè)計(jì)器中設(shè)置Tab鍵順序,讀者也可以在幫助索引中查看 Qt DeSigner's Tab Order Editing Mode 關(guān)鍵字。
轉(zhuǎn)載于:https://www.cnblogs.com/linuxAndMcu/p/10124513.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的Qt窗口部件与布局之二:布局管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ActiveMQ_3Java实现
- 下一篇: 数据量庞大的分页穿梭框实现