QT 中怎樣使得控制元件與 介面等比例變化
轉自:https://github.com/exoticknight/blog-post/blob/master/python-with-Qt-application-development/python%20%C3%97%20Qt%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%20%C2%B7%202%20--%20%E7%95%8C%E9%9D%A2%E5%88%9D%E6%AD%A5%E8%AE%BE%E8%AE%A1.md
之前的一篇可以算是前置知識的快速介紹。從這篇開始就是正式地編寫應用了。
為了兼顧舉舉例子和真實性,選了這麼一個應用:PQ筆記。基本的功能如下:
- 筆記支援富文字貼上
- 按資料夾分類筆記
畫出大概的樣子
先來一個大概的設計圖。
就是一個規規矩矩的三欄佈局,左邊是筆記本的目錄樹,中間是文件列表,右邊是文件內容。這個只是現階段的大概構思,最終做出來不一定是這樣的,有可能在一些細節上會有所更改,但是整體介面幾乎都可以定下來了。
開啟ui_mainwindow.ui
,從Containers
里拉出三個Widget
,分別命名為widgetLeft
、widgetMiddle
和widgetRight
。這就是左中右三欄的容器。
在左邊欄中拖入一個pushButton
和一個treeView
,分別對應設計圖上的兩個控制元件。注意,如果拖放位置正確(也就是QtDesigner知道你要將控制元件放進左邊欄裡面),你會看到左邊欄widgetLeft
對著左邊欄空白處點選右鍵,依次選擇佈局
-> 垂直佈局
。
可以看到控制元件非常聽話地從上到下排列好了。這裡為widget中的控制元件快速設定了一個佈局,相當於告訴widget中的控制元件該如何顯示自己。
注意,這個"佈局"並不是widget中的屬性,而是獨立的另一個類QLayout
及其子類的例項。在物件檢視器中點選widgetLeft
後在下面的屬性編輯器中可以看到有一欄Layout
,這個才是控制元件們服服帖帖的原因。只不過,當為一個widget
選擇了佈局之後,QtDesigner自動給這個widget增加了一個佈局,然後將widget裡面的子控制元件加入到佈局中,於是子控制元件們都知道應該如何顯示了。
同理,在中間控制元件widgetMiddle
中放入一個LineEdit
和一個ListView
,在右邊控制元件widgetRight
中放入TextEdit
,並且設定好佈局。
現在使用快捷鍵Ctrl + r
預覽,發現拉伸視窗的時候,裡面的三欄控制元件沒有任何反應,這可不是想要的效果。
注意整個視窗其實也是一個widget,同樣需要為其設定佈局。
再預覽,出現一個新問題:三個欄不能各自調整大小。
要實現這個功能需要另外一種佈局管理,分裂器(QSplitter)。分裂器允許元素調整各自的大小。
先打破布局。
按著ctrl選擇三個分欄widget,注意是分欄widget,再在其中一個widget的空白處點選右鍵,在佈局中可以看到有使用分裂器水平佈局
。
最後為視窗應用垂直佈局就可以了。預覽的時候當滑鼠移動到分欄控制元件之間會發現可以調整大小了,同時調整視窗也能影響到三個分欄的大小。
從實際來說,調整視窗的大小的時候,更多是希望調整右邊欄即文件顯示欄的大小。
QSplitter還能設定一些細節。
找到QSplitter
的屬性:
- orientation,控制元件排列方向,水平還是垂直
- opaqueResize,是否實時顯示調整
- handleWidth,調整條的寬度
- childrenCollapsible,控制元件調整成過小時是否會隱藏
似乎沒有什麼可以用的。
然而,問題的解決方法卻不在QSplitter
上,而在其子元件上。
實際上,幾乎所有的widget,都有一個sizePolicy
的屬性,而在此屬性中,有子屬性Horizontal Stretch
和Vertical
Stretch
,對應中文水平伸展
和垂直伸展
,決定水平和垂直的縮放比例。
在屬性編輯器中,可以看到水平伸展
的值預設為0,也就是左欄:中欄:右欄 = 0:0:0,現在將右欄的水平伸展
值設為1,也就是左欄:中欄:右欄
= 0:0:1。
預覽一下,效果就出來了。
原理應該是這樣的,在視窗縮放的時候,預設的配置是 0:0:0,表示變化被平均分配到兩個元件上了。而修改後子元件們根據已經設定好的比例 0:0:1,所有的因視窗縮放而引起的大小變化全部被分配到文件編輯元件上了。
佈局管理(Layout Management)
佈局可以在Widget Box
裡面看到,提供的有四個佈局:
- Vertical Layout
- Horizontal Layout
- Grid Layout
- Form Layout
分別是垂直佈局、水平佈局、網格佈局和表單佈局。當然還有另外的自動佈局,但是這四個基本能滿足普通需要。
垂直/水平佈局不用解釋了。網格佈局是類似表格,一個控制元件佔據一個單元格位置;表單佈局是類似平常表單,從上到下排成多行,每行分兩欄,左邊放標籤控制元件,右邊放輸入框控制元件。
選單
在新建一個窗體的時候,QtDesigner就已經為窗體新增上了QMenuBar
,在窗體的標題欄下面可以看到一個經典的選單欄,上面有在這裡輸入
字樣。只要雙擊並填上你希望顯示的選單名字,QtDesigner會自動生成一個選單,在下拉列表上繼續雙擊在這裡輸入
將會自動生成QAction
。QAction
才是真正代表著選單裡的某個動作。
在下拉選單裡面,還能看到一個新增分隔符
,是新增一個分割線的意思。當生成了一個QAction
之後,可以看到右邊有一個類似加號的圖示,是將當前QAction
轉化為QMenu
的意思,換句話說可以生成子級選單。子級選單的操作跟上面描述的選單操作一模一樣。
另外給各個action物件修改好名字,以供日後呼叫。