轉自: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對象修改好名字,以供日后調用。