PyQT5 之 Qt Designer 介绍与入门
?
From:https://www.jianshu.com/p/5b063c5745d0
養薛定諤的貓 簡書:https://www.jianshu.com/u/bf82b363ae88
?
?
Qt Designer 的介紹
?
在PyQt中編寫UI界面可以直接通過代碼來實現,也可以通過Qt Designer來完成。Qt Designer的設計符合MVC的架構,其實現了視圖和邏輯的分離,從而實現了開發的便捷。Qt Designer中的操作方式十分靈活,其通過拖拽的方式放置控件可以隨時查看控件效果。Qt Designer生成的.ui文件(實質上是XML格式的文件)也可以通過pyuic5工具轉換成.py文件。
Qt Designer隨PyQt5-tools包一起安裝,其安裝路徑在 “Python安裝路徑\Lib\site-packages\pyqt5-tools”下。
若要啟動Qt Designer可以直接到上述目錄下,雙擊designer.exe打開Qt Designer;或將上述路徑加入環境變量,在命令行輸入designer打開;或在PyCharm中將其配置為外部工具打開。
下面以PyCharm為例,講述PyCharm中Qt Designer的配置方法。
?
?
PyCharm 中 PyQt5 工具配置
?
打開PyCharm,選擇Settings -> Tools -> External Tools,點擊左上角的綠色加號。
Name填入QtDesigner(方便后續使用,名稱無所謂)。Program選擇我們安裝的PyQt5-tools下面的designer.exe。Working directory則選擇我們的工作目錄。然后點擊OK,則添加了QtDesigner作為PyCharm的外置工具。
然后添加PyUIC(UI轉換工具),PyUIC的Program為Python.exe,在Python的安裝目錄下面的Scripts目錄下,Working directory同理設為我們的工作目錄,Arguments則填入如下代碼:
最后添加pyrcc用于PyQt5的資源文件轉碼。具體配置與上述內容相同,Arguments填入:
$FileName$ -o $FileNameWithoutExtension$_rc.py退出之前,點擊Apply保存配置。配置完成之后,PyCharm中會加入3個工具。
?
?
Qt Designer 界面簡介
?
點擊 QtDesigner 打開 QtDesigner 的界面,彈出如下圖所示的窗口。
創建新的 Form 給出了5個模板,其中 Widget 與 MainWindow 最為常用。這里我們選擇創建一個 MainWindow。
上面界面的最左側菜單為Widget Box,Widget Box中包含PyQt5中的所有Widget組件,我們可以從左側的Widget Box中拖拽出諸如Button、View和Input等組件到中間的窗口中。
點擊Form -> Preview(快捷鍵為Ctrl+R)則可以預覽我們設計好的界面,也可以用Preview In來選擇在相應的主題風格下預覽。
我們拖拽一個Label與Button進入主窗口(Main Window)。
此時在右上角的Object Inspector(對象查看器)中可以看到主窗口中的已放置的對象(label與pushButton)以及其相應地Qt類。
以Label為例,此時我們點擊Main Window中的label或是在Object Inspector中選取label后,查看右側的一塊區域——Property Editor(屬性編輯器)。
其主要包含屬性有如下:
| objectName | 控件對象名稱 |
| geometry | 相應寬和高與坐標 |
| sizePolicy | 控件大小的策略 |
| minimumSize | 最小的寬和高 |
| maximumSize | 最大的寬和高 |
| font | 字體 |
| cursor | 光標 |
| ... | ... |
PS:將minimumSize和maximumSize設為一樣的數值之后,則窗口的大小固定。
最右下角的部分則為Resource Browser(資源瀏覽器),資源瀏覽器中可以添加相應地如圖片素材,作為Label或Button等控件的背景圖片等。
?
?
Qt Designer 的 UI 文件
?
使用Qt Designer設計保存的文件為.ui格式的文件。
通過保存并使用記事本等軟件打開,我們可以看到.ui文件的內容如下:
從.ui文件的第一行我們便能看出,其實質是一個XML文件。ui文件中存放了在主窗口中的一切控件的相關屬性。使用XML文件來存儲UI文件,具有高可讀性和移植性,因此我們可以方便地將.ui文件轉換到.py文件,從而使得我們可以使用Python語言在設計的GUI上面編程。
?
?
將.ui文件轉換為.py文件
?
將.ui文件轉換到.py文件很簡單,在前面我們曾設置了pyuic5這個工具。如果你沒有在PyCharm中設置這個工具,或者根本沒有使用PyCharm,則可以到命令行中使用如下命令實現.ui到.py的轉換。
pyuic5 - o 目標文件名.py 源文件名.ui或者直接在PyCharm中,找到.ui文件,右鍵 打開菜單找到External Tools->PyUIC。點擊之后,我們在相應工程目錄下會產生一個.py文件。(注意,.ui文件必須存放在我們的External Tools中設置的相應項目目錄下)
轉換完成之后,打開.py文件。
# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'mainWindow.ui' # # Created by: PyQt5 UI code generator 5.10.1 # # WARNING! All changes made in this file will be lost!from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(800, 600)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.label = QtWidgets.QLabel(self.centralwidget)self.label.setGeometry(QtCore.QRect(240, 80, 72, 15))self.label.setObjectName("label")self.pushButton = QtWidgets.QPushButton(self.centralwidget)self.pushButton.setGeometry(QtCore.QRect(240, 120, 93, 28))self.pushButton.setObjectName("pushButton")MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))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.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))self.label.setText(_translate("MainWindow", "TextLabel"))self.pushButton.setText(_translate("MainWindow", "PushButton"))觀察上述文件,可以看到如果不通過Qt Designer來制作界面的話,我們將會一次次地調試程序,來講按鈕和Label等放在合適的位置,這將是極其痛苦的過程。而通過Qt Designer,我們可以快速地制作UI,并生成Python的代碼,從而實現快速地UI的開發。
?
?
使用轉換的.py文件
?
然而,此時之間運行這個轉換好的Python文件是無法顯示任何窗口的。因為這個Python文件只有定義主窗口以及其控件的代碼,并沒有程序入口的代碼。為了秉持視圖與邏輯分離的原則,我們再編寫一個新的腳本來調用這個文件,并且創建一個窗口。
import sys from PyQt5.QtWidgets import QApplication, QMainWindow from mainWindow import *class MyWindow(QMainWindow, Ui_MainWindow):def __init__(self, parent=None):super(MyWindow, self).__init__(parent)self.setupUi(self)if __name__ == '__main__':app = QApplication(sys.argv)myWin = MyWindow()myWin.show()sys.exit(app.exec_())通過上述代碼,我們繼承了Ui_MainWindow類,使用其構造方法構造主窗口,并定義了程序的入口,通過創建QApplication對象來創建Qt窗口。其運行結果如下:
通過上述操作,我們熟悉了Qt Designer設計界面,到實現業務邏輯的大致工作流程。通過這個工作流程可以簡化工作,實現速度的提升。
通過對視圖與業務邏輯的分離,在每次更改Qt Designer的UI設計的時候,也不用重新編寫代碼,而只需對更改的部分做稍微的修改即可。
?
?
PyQT5速成教程-3 布局管理
?
PyQt5學習入門-3-Qt Designer布局:https://blog.csdn.net/qq_22238533/article/details/78952706
使用Qt Designer來設計界面:https://blog.csdn.net/a10929/article/details/78114261
?
布局(Layout)管理
Qt Designer中,在工具箱中最上方可以看到有4種布局。分別是垂直布局、水平布局、柵格布局和表單布局。
| 垂直(Vertical)布局 | 布局內的控件按照從上到下的順序縱向排列 |
| 水平(Horizontal)布局 | 布局內的控件按照從左到右的順序橫向排列 |
| 柵格(Grid)布局 | 將控件放入柵格中,然后劃分成若干行與若干列,并且將每個窗口控件放在合適的單元中 |
| 表單(Form)布局 | 控件以兩列布局在表單中,左列包含標簽,右列包含輸入控件 |
在Qt Designer中實現布局有兩種方式,通過布局管理器進行布局和通過容器控件進行布局。
?
布局管理器
讓我們在左側的工具箱中隨意拖動一些諸如按鈕、標簽、輸入框等控件到主窗口中。
由于剛才是隨意拖拽至主窗口,因此所有控件的排放是亂七八糟的。此時,我們不選中任何控件,在空白處點擊右鍵,找到彈出菜單最下方的Layout布局。
可以看到,在右鍵菜單中可以指定布局的方式以及相應布局方式的快捷鍵。這里我們選擇Lay Out Vertically(垂直布局),整個主窗口內的所有控件一瞬間都垂直著排列整齊了。
此時如果需要調整垂直布局的順序,只需按住待調整的控件,上下拖動即可。但是這樣布局是針對整個窗口的,有時我們需要讓不同的布局有父子關系的繼承。那么這時就不能單純地在空白的地方點擊右鍵來布局了。
讓我們再次點擊右鍵 -> Lay Out -> Break Lay Out來打開(取消)布局。選中需要水平布局的2個控件,選中后點擊右鍵,水平布局。再選中另外兩個控件,選擇水平布局。此時的主窗口應該如圖所示:
最后,我們再將兩個布局選中,點擊右鍵垂直布局,來排列兩個水平布局。
最后在空白區域再次使用垂直布局。這樣即使我們縮放窗口,整個窗口內的控件也會跟著窗口的變化做出相應改變了。
在上述操作的過程中,我們的一系列操作有決定這些物體的父子關系(層級關系)。而其層級關系在對象查看器中可以直觀地看出。
?
布局管理生成的代碼
讓我們把前面制作的布局保存為.ui文件,并使用PyUIC轉換為.py文件。
...self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.centralwidget)self.verticalLayout_4.setObjectName("verticalLayout_4")self.verticalLayout_3 = QtWidgets.QVBoxLayout()self.verticalLayout_3.setObjectName("verticalLayout_3")self.horizontalLayout = QtWidgets.QHBoxLayout()self.horizontalLayout.setObjectName("horizontalLayout")self.label = QtWidgets.QLabel(self.centralwidget)self.label.setObjectName("label")self.horizontalLayout.addWidget(self.label)self.checkBox = QtWidgets.QCheckBox(self.centralwidget)self.checkBox.setObjectName("checkBox")self.horizontalLayout.addWidget(self.checkBox)self.verticalLayout_3.addLayout(self.horizontalLayout)self.horizontalLayout_2 = QtWidgets.QHBoxLayout()self.horizontalLayout_2.setObjectName("horizontalLayout_2")self.radioButton = QtWidgets.QRadioButton(self.centralwidget)self.radioButton.setObjectName("radioButton")self.horizontalLayout_2.addWidget(self.radioButton)self.pushButton = QtWidgets.QPushButton(self.centralwidget)self.pushButton.setObjectName("pushButton")self.horizontalLayout_2.addWidget(self.pushButton)self.verticalLayout_3.addLayout(self.horizontalLayout_2)self.verticalLayout_4.addLayout(self.verticalLayout_3)MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 241, 26))self.menubar.setObjectName("menubar")MainWindow.setMenuBar(self.menubar)self.statusbar = QtWidgets.QStatusBar(MainWindow)self.statusbar.setObjectName("statusbar")MainWindow.setStatusBar(self.statusbar) ...從上面的代碼中,我們找到關鍵的幾行。如定義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 input和button到Frame中。此時Frame中的控件應該是如下圖:
但選中Frame控件,點擊右鍵-> Lay Out -> Lay Out Horizontally 則會自動水平排列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屬性的四個值。通過以上的方法,我們可以對任何一個控件進行布局。
?
?
Qt Designer實戰 -?設計一個計算器界面
?
使用網格布局(Grid Layout)
首先分析我們的整數計算器需要的一些按鈕:
數字鍵:0-9共10個。
操作符:+ - * / = CE共6個
當我們在Qt Designer的主窗口中創建上述16個按鈕之后,按照4行4列的順序進行擺放。
并且修改按鈕的屬性中的objectName為相對于的名稱。如數字0的objectName設置為Num_0,操作符+的objectName設置為OP_plus。對于按鈕的顯示名稱的修改,在主窗口中雙擊相應按鈕則可以快速修改。
由于計算器中的按鈕是正方形的(我們通常會選擇正方形),而且不想讓這些按鈕根據窗口的大小進行變化,通過全選16個按鈕(在主窗口中使用鼠標左鍵拖出選擇框,選中16個按鈕)在右側找到mininumSize和maximumSize屬性。點擊其左面的箭頭符號展開選項,將其寬和高固定為60。這樣就不會因為縮放窗口而造成按鈕的大小變化了。
在對所有按鈕完成相應操作之后,我們選中16個按鈕,點擊右鍵,使用網格布局來實現布局。
?
使用Spacer增加空白間隔
我們在計算器上面新建一個Line Edit用來顯示輸入結果與計算結果。
通過在空白地方右鍵,對主窗口使用Vertical Lay Out。
此時,我們實現了一個計算器的布局。但顯示框與下面的鍵盤舉例太過近了。這時我們便需要使用左側工具箱內的Spacer控件。
Spacer顧名思義,分隔器。可以通過以占位的形式來將布局中的不同控件分開部分舉例。
此時,我們拖動一個Vertical Spacer到Line Edit與下面的鍵盤之間。同樣,Horizontal Spacer也可以用來水平地分離控件之間的距離。
雖然Spacer在我們的Qt Designer編輯器中是以藍色的類似彈簧的外觀存在的,但是在真正的窗體中,Spacer是隱形的。
但這時的Spacer大小和Line Edit的大小都不是我想要的,而且也無法通過鼠標來拖動。如果想要改變這些,則需要進一步了解這些控件的一些屬性。
?
sizePolicy 尺寸策略
在Qt Designer中,控件的尺寸是可以變化的。每個控件都擁有sizeHint和minisizeHint兩個尺寸。其一,sizeHint即尺寸提示;其二,minisizeHint則是最小尺寸。尺寸提示也是控件的期望尺寸,最小尺寸即窗口可以被壓縮到的最小的尺寸。sizePolicy與sizeHint和minisizeHint息息相關。
對于布局管理器中的布局無法滿足我們的要求的時候,sizePolicy屬性便派上了用場。
sizePolicy可以實現控件的微調。sizePolicy中共有如下幾種水平和垂直策略。
?
| Fixed | 固定 | 窗口控件具有sizeHint提示的尺寸且尺寸不變 |
| Minimum | 最小 | 窗口控件的sizeHint提示的尺寸即最小尺寸,窗口控件不能比這個值小,但是可以變大 |
| Maximum | 最大 | 窗口控件的sizeHint提示的尺寸即最大尺寸,窗口控件不能比這個值大,但是可以壓縮到minisizeHint的尺寸 |
| Preferred | 期望 | 窗口控件的sizeHint提示的尺寸是期望的尺寸,可以壓縮到minisizeHint尺寸,也可以比sizeHint尺寸更大 |
| MinimumExpanding | 最小擴展 | 窗口控件的sizeHint提示的尺寸是最小尺寸,不能縮得比這個尺寸小,但是這個控件期望可以比這個尺寸大 |
| Expanding | 擴展 | 窗口控件可以縮小到minisizeHint的尺寸,也可以比sizeHint的的尺寸大,但期望是更大 |
| Ignored | 忽略 | 無視窗口控件的sizeHint與minisizeHint,按照默認來設置 |
在sizePolicy的Horizontal Policy和Vertical Policy下面還有Horizontal Stretch和Vertical Stretch兩個屬性。
讓我們找到Spacer,并修改其屬性的Height為10。
并將其sizeType修改為Fixed固定。此時,觀察左面的計算器的主界面顯示欄Line Edit與下面的鍵盤之間的間距變小了。
?
?
?
?
總結
以上是生活随笔為你收集整理的PyQT5 之 Qt Designer 介绍与入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 这个C怎么了?求大佬指教
- 下一篇: s3c2440移植MQTT