PyQT5 PyQT入門教程(之二)


REF

https://www.jianshu.com/p/3832eb48f3d5

 

布局(Layout)管理

Qt Designer中,在工具箱中最上方可以看到有4種布局。分別是垂直布局、水平布局、柵格布局和表單布局


 

 


四種布局
布局名稱     布局含義
垂直(Vertical)布局     布局內的控件按照從上到下的順序縱向排列
水平(Horizontal)布局     布局內的控件按照從左到右的順序橫向排列
柵格(Grid)布局     將控件放入柵格中,然后划分成若干行與若干列,並且將每個窗口控件放在合適的單元中
表單(Form)布局     控件以兩列布局在表單中,左列包含標簽,右列包含輸入控件

在Qt Designer中實現布局有兩種方式,通過布局管理器進行布局和通過容器控件進行布局。
布局管理器

讓我們在左側的工具箱中隨意拖動一些諸如按鈕、標簽、輸入框等控件到主窗口中。

很隨意的主窗口

 

 


由於剛才是隨意拖拽至主窗口,因此所有控件的排放是亂七八糟的。此時,我們不選中任何控件,在空白處點擊右鍵,找到彈出菜單最下方的Layout布局。

右鍵菜單

 

 


可以看到,在右鍵菜單中可以指定布局的方式以及相應布局方式的快捷鍵。這里我們選擇Lay Out Vertically(垂直布局),整個主窗口內的所有控件一瞬間都垂直着排列整齊了。
垂直布局的效果

 

 


此時如果需要調整垂直布局的順序,只需按住待調整的控件,上下拖動即可。但是這樣布局是針對整個窗口的,有時我們需要讓不同的布局有父子關系的繼承。那么這時就不能單純地在空白的地方點擊右鍵來布局了。
讓我們再次點擊 右鍵 -> Lay Out -> Break LayOut 來打開(取消)布局。

 

 

選中需要水平布局的2個控件(ctrl+鼠標單擊),選中后點擊右鍵,水平布局。再選中另外兩個控件(ctrl+鼠標單擊),選擇水平布局。此時的主窗口應該如圖所示:

 

 


2個水平布局

最后,我們再將兩個布局選中(框選),點擊右鍵垂直布局,來排列兩個水平布局。
將兩個水平布局垂直布局

 

 


最后在空白區域再次使用垂直布局。這樣即使我們縮放窗口,整個窗口內的控件也會跟着窗口的變化做出相應改變了。
最終效果

 

 


在上述操作的過程中,我們的一系列操作有決定這些物體的父子關系(層級關系)。而其層級關系在對象查看器中可以直觀地看出。

 

 


對象查看器中的層級關系

 


布局管理生成的代碼

讓我們把前面制作的布局保存為.ui文件,並使用PyUIC轉換為.py文件。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'firstQTui2.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(488, 303)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout.addWidget(self.pushButton)
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setObjectName("label")
        self.horizontalLayout.addWidget(self.label)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.checkBox = QtWidgets.QCheckBox(self.centralwidget)
        self.checkBox.setObjectName("checkBox")
        self.horizontalLayout_2.addWidget(self.checkBox)
        self.radioButton = QtWidgets.QRadioButton(self.centralwidget)
        self.radioButton.setObjectName("radioButton")
        self.horizontalLayout_2.addWidget(self.radioButton)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.verticalLayout_2.addLayout(self.verticalLayout)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 488, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))
        self.label.setText(_translate("MainWindow", "TextLabel"))
        self.checkBox.setText(_translate("MainWindow", "CheckBox"))
        self.radioButton.setText(_translate("MainWindow", "RadioButton"))

 


從上面的代碼中,我們找到關鍵的幾行。如定義label的時候,是如下代碼:

        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setObjectName("label")
        self.horizontalLayout.addWidget(self.label)


其中,最后一行將label添加為了horizontalLayout的子物體。

        self.horizontalLayout_2.addWidget(self.pushButton)
        self.verticalLayout_3.addLayout(self.horizontalLayout_2)
        self.verticalLayout_4.addLayout(self.verticalLayout_3)



后面的幾行代碼,如verticalLayout_3將horizontalLayout_2作為了其子物體;verticalLayout_4將verticalLayout_3作為了其子物體。這些都是與我們在Qt Designer中做的操作是一樣的。


使用容器進行布局

容器(Container)指的就是能容納其他子控件的一個控件。使用容器控件可以將容器控件中的所有控件歸為一類,從而區別於其他的控件。當然,正如上文提到過的,使用容器也可以對控件進行布局。

 

 


工具盒中的容器控件

首先,從左側的Container中拖出一個Frame控件到主窗口中,再拖出一個label、line edit和push button到Frame中。此時Frame中的控件應該是如下圖:

 

 


雜亂的Frame

但選中Frame控件,點擊 右鍵-> Lay Out -> Lay Out Horizontally 則會自動水平排列Frame中的三個控件。

 

 


水平布局Frame中的控件

當我們需要變更Frame的位置的時候,可以直接拖動Frame到相應地位置,這樣管理更加方便。使用容器進行布局的實質也是使用容器管理器進行布局的。
絕對布局

我們前面的學習重點放在了布局管理器上面。但是最簡單的布局則是之間輸入控件的Geometry屬性值。

 

 


屬性編輯器


在屬性編輯器中,我們通過修改X Y值來將控件放置在相應地位置,通過修改Width和Height來更改其高度。讓我們通過如下表格來解讀一下這個Button的Geometry屬性。
名稱     值     含義
X     290     控件的最左上角距離主窗口的左側290px
Y     140     控件的最左上角距離主窗口的上方140px
Width     93     按鈕的寬度為93px
Height     28     按鈕的高度為23px

而上述的Geometry屬性在.py代碼中是如下體現的:

self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(290, 140, 93, 28))
self.pushButton.setObjectName("pushButton")

 



可以看到,上述代碼的第二行通過setGeometry方法指定了Geometry屬性的四個值。通過以上的方法,我們可以對任何一個控件進行布局。

 

下一篇: PyQT5 入門教程(之三)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM