PyQT5 之 Qt Designer 介绍与入门
?
From:https://www.jianshu.com/p/5b063c5745d0
養(yǎng)薛定諤的貓 簡書:https://www.jianshu.com/u/bf82b363ae88
?
?
Qt Designer 的介紹
?
在PyQt中編寫UI界面可以直接通過代碼來實(shí)現(xiàn),也可以通過Qt Designer來完成。Qt Designer的設(shè)計(jì)符合MVC的架構(gòu),其實(shí)現(xiàn)了視圖和邏輯的分離,從而實(shí)現(xiàn)了開發(fā)的便捷。Qt Designer中的操作方式十分靈活,其通過拖拽的方式放置控件可以隨時(shí)查看控件效果。Qt Designer生成的.ui文件(實(shí)質(zhì)上是XML格式的文件)也可以通過pyuic5工具轉(zhuǎn)換成.py文件。
Qt Designer隨PyQt5-tools包一起安裝,其安裝路徑在 “Python安裝路徑\Lib\site-packages\pyqt5-tools”下。
若要啟動(dòng)Qt Designer可以直接到上述目錄下,雙擊designer.exe打開Qt Designer;或?qū)⑸鲜雎窂郊尤氕h(huán)境變量,在命令行輸入designer打開;或在PyCharm中將其配置為外部工具打開。
下面以PyCharm為例,講述PyCharm中Qt Designer的配置方法。
?
?
PyCharm 中 PyQt5 工具配置
?
打開PyCharm,選擇Settings -> Tools -> External Tools,點(diǎn)擊左上角的綠色加號(hào)。
Name填入QtDesigner(方便后續(xù)使用,名稱無所謂)。Program選擇我們安裝的PyQt5-tools下面的designer.exe。Working directory則選擇我們的工作目錄。然后點(diǎn)擊OK,則添加了QtDesigner作為PyCharm的外置工具。
然后添加PyUIC(UI轉(zhuǎn)換工具),PyUIC的Program為Python.exe,在Python的安裝目錄下面的Scripts目錄下,Working directory同理設(shè)為我們的工作目錄,Arguments則填入如下代碼:
最后添加pyrcc用于PyQt5的資源文件轉(zhuǎn)碼。具體配置與上述內(nèi)容相同,Arguments填入:
$FileName$ -o $FileNameWithoutExtension$_rc.py退出之前,點(diǎn)擊Apply保存配置。配置完成之后,PyCharm中會(huì)加入3個(gè)工具。
?
?
Qt Designer 界面簡介
?
點(diǎn)擊 QtDesigner 打開 QtDesigner 的界面,彈出如下圖所示的窗口。
創(chuàng)建新的 Form 給出了5個(gè)模板,其中 Widget 與 MainWindow 最為常用。這里我們選擇創(chuàng)建一個(gè) MainWindow。
上面界面的最左側(cè)菜單為Widget Box,Widget Box中包含PyQt5中的所有Widget組件,我們可以從左側(cè)的Widget Box中拖拽出諸如Button、View和Input等組件到中間的窗口中。
點(diǎn)擊Form -> Preview(快捷鍵為Ctrl+R)則可以預(yù)覽我們?cè)O(shè)計(jì)好的界面,也可以用Preview In來選擇在相應(yīng)的主題風(fēng)格下預(yù)覽。
我們拖拽一個(gè)Label與Button進(jìn)入主窗口(Main Window)。
此時(shí)在右上角的Object Inspector(對(duì)象查看器)中可以看到主窗口中的已放置的對(duì)象(label與pushButton)以及其相應(yīng)地Qt類。
以Label為例,此時(shí)我們點(diǎn)擊Main Window中的label或是在Object Inspector中選取label后,查看右側(cè)的一塊區(qū)域——Property Editor(屬性編輯器)。
其主要包含屬性有如下:
| objectName | 控件對(duì)象名稱 |
| geometry | 相應(yīng)寬和高與坐標(biāo) |
| sizePolicy | 控件大小的策略 |
| minimumSize | 最小的寬和高 |
| maximumSize | 最大的寬和高 |
| font | 字體 |
| cursor | 光標(biāo) |
| ... | ... |
PS:將minimumSize和maximumSize設(shè)為一樣的數(shù)值之后,則窗口的大小固定。
最右下角的部分則為Resource Browser(資源瀏覽器),資源瀏覽器中可以添加相應(yīng)地如圖片素材,作為Label或Button等控件的背景圖片等。
?
?
Qt Designer 的 UI 文件
?
使用Qt Designer設(shè)計(jì)保存的文件為.ui格式的文件。
通過保存并使用記事本等軟件打開,我們可以看到.ui文件的內(nèi)容如下:
從.ui文件的第一行我們便能看出,其實(shí)質(zhì)是一個(gè)XML文件。ui文件中存放了在主窗口中的一切控件的相關(guān)屬性。使用XML文件來存儲(chǔ)UI文件,具有高可讀性和移植性,因此我們可以方便地將.ui文件轉(zhuǎn)換到.py文件,從而使得我們可以使用Python語言在設(shè)計(jì)的GUI上面編程。
?
?
將.ui文件轉(zhuǎn)換為.py文件
?
將.ui文件轉(zhuǎn)換到.py文件很簡單,在前面我們?cè)O(shè)置了pyuic5這個(gè)工具。如果你沒有在PyCharm中設(shè)置這個(gè)工具,或者根本沒有使用PyCharm,則可以到命令行中使用如下命令實(shí)現(xiàn).ui到.py的轉(zhuǎn)換。
pyuic5 - o 目標(biāo)文件名.py 源文件名.ui或者直接在PyCharm中,找到.ui文件,右鍵 打開菜單找到External Tools->PyUIC。點(diǎn)擊之后,我們?cè)谙鄳?yīng)工程目錄下會(huì)產(chǎn)生一個(gè).py文件。(注意,.ui文件必須存放在我們的External Tools中設(shè)置的相應(yīng)項(xiàng)目目錄下)
轉(zhuǎn)換完成之后,打開.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來制作界面的話,我們將會(huì)一次次地調(diào)試程序,來講按鈕和Label等放在合適的位置,這將是極其痛苦的過程。而通過Qt Designer,我們可以快速地制作UI,并生成Python的代碼,從而實(shí)現(xiàn)快速地UI的開發(fā)。
?
?
使用轉(zhuǎn)換的.py文件
?
然而,此時(shí)之間運(yùn)行這個(gè)轉(zhuǎn)換好的Python文件是無法顯示任何窗口的。因?yàn)檫@個(gè)Python文件只有定義主窗口以及其控件的代碼,并沒有程序入口的代碼。為了秉持視圖與邏輯分離的原則,我們?cè)倬帉懸粋€(gè)新的腳本來調(diào)用這個(gè)文件,并且創(chuàng)建一個(gè)窗口。
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類,使用其構(gòu)造方法構(gòu)造主窗口,并定義了程序的入口,通過創(chuàng)建QApplication對(duì)象來創(chuàng)建Qt窗口。其運(yùn)行結(jié)果如下:
通過上述操作,我們熟悉了Qt Designer設(shè)計(jì)界面,到實(shí)現(xiàn)業(yè)務(wù)邏輯的大致工作流程。通過這個(gè)工作流程可以簡化工作,實(shí)現(xiàn)速度的提升。
通過對(duì)視圖與業(yè)務(wù)邏輯的分離,在每次更改Qt Designer的UI設(shè)計(jì)的時(shí)候,也不用重新編寫代碼,而只需對(duì)更改的部分做稍微的修改即可。
?
?
PyQT5速成教程-3 布局管理
?
PyQt5學(xué)習(xí)入門-3-Qt Designer布局:https://blog.csdn.net/qq_22238533/article/details/78952706
使用Qt Designer來設(shè)計(jì)界面:https://blog.csdn.net/a10929/article/details/78114261
?
布局(Layout)管理
Qt Designer中,在工具箱中最上方可以看到有4種布局。分別是垂直布局、水平布局、柵格布局和表單布局。
| 垂直(Vertical)布局 | 布局內(nèi)的控件按照從上到下的順序縱向排列 |
| 水平(Horizontal)布局 | 布局內(nèi)的控件按照從左到右的順序橫向排列 |
| 柵格(Grid)布局 | 將控件放入柵格中,然后劃分成若干行與若干列,并且將每個(gè)窗口控件放在合適的單元中 |
| 表單(Form)布局 | 控件以兩列布局在表單中,左列包含標(biāo)簽,右列包含輸入控件 |
在Qt Designer中實(shí)現(xiàn)布局有兩種方式,通過布局管理器進(jìn)行布局和通過容器控件進(jìn)行布局。
?
布局管理器
讓我們?cè)谧髠?cè)的工具箱中隨意拖動(dòng)一些諸如按鈕、標(biāo)簽、輸入框等控件到主窗口中。
由于剛才是隨意拖拽至主窗口,因此所有控件的排放是亂七八糟的。此時(shí),我們不選中任何控件,在空白處點(diǎn)擊右鍵,找到彈出菜單最下方的Layout布局。
可以看到,在右鍵菜單中可以指定布局的方式以及相應(yīng)布局方式的快捷鍵。這里我們選擇Lay Out Vertically(垂直布局),整個(gè)主窗口內(nèi)的所有控件一瞬間都垂直著排列整齊了。
此時(shí)如果需要調(diào)整垂直布局的順序,只需按住待調(diào)整的控件,上下拖動(dòng)即可。但是這樣布局是針對(duì)整個(gè)窗口的,有時(shí)我們需要讓不同的布局有父子關(guān)系的繼承。那么這時(shí)就不能單純地在空白的地方點(diǎn)擊右鍵來布局了。
讓我們?cè)俅吸c(diǎn)擊右鍵 -> Lay Out -> Break Lay Out來打開(取消)布局。選中需要水平布局的2個(gè)控件,選中后點(diǎn)擊右鍵,水平布局。再選中另外兩個(gè)控件,選擇水平布局。此時(shí)的主窗口應(yīng)該如圖所示:
最后,我們?cè)賹蓚€(gè)布局選中,點(diǎn)擊右鍵垂直布局,來排列兩個(gè)水平布局。
最后在空白區(qū)域再次使用垂直布局。這樣即使我們縮放窗口,整個(gè)窗口內(nèi)的控件也會(huì)跟著窗口的變化做出相應(yīng)改變了。
在上述操作的過程中,我們的一系列操作有決定這些物體的父子關(guān)系(層級(jí)關(guān)系)。而其層級(jí)關(guān)系在對(duì)象查看器中可以直觀地看出。
?
布局管理生成的代碼
讓我們把前面制作的布局保存為.ui文件,并使用PyUIC轉(zhuǎn)換為.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) ...從上面的代碼中,我們找到關(guān)鍵的幾行。如定義label的時(shí)候,是如下代碼:
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作為了其子物體。這些都是與我們?cè)赒t Designer中做的操作是一樣的。
?
使用容器進(jìn)行布局
容器(Container)指的就是能容納其他子控件的一個(gè)控件。使用容器控件可以將容器控件中的所有控件歸為一類,從而區(qū)別于其他的控件。當(dāng)然,正如上文提到過的,使用容器也可以對(duì)控件進(jìn)行布局。
首先,從左側(cè)的Container中拖出一個(gè)Frame控件到主窗口中,再拖出一個(gè)label、line input和button到Frame中。此時(shí)Frame中的控件應(yīng)該是如下圖:
但選中Frame控件,點(diǎn)擊右鍵-> Lay Out -> Lay Out Horizontally 則會(huì)自動(dòng)水平排列Frame中的三個(gè)控件。
當(dāng)我們需要變更Frame的位置的時(shí)候,可以直接拖動(dòng)Frame到相應(yīng)地位置,這樣管理更加方便。使用容器進(jìn)行布局的實(shí)質(zhì)也是使用容器管理器進(jìn)行布局的。
?
絕對(duì)布局
我們前面的學(xué)習(xí)重點(diǎn)放在了布局管理器上面。但是最簡單的布局則是之間輸入控件的Geometry屬性值。
在屬性編輯器中,我們通過修改X Y值來將控件放置在相應(yīng)地位置,通過修改Width和Height來更改其高度。讓我們通過如下表格來解讀一下這個(gè)Button的Geometry屬性。
| X | 290 | 控件的最左上角距離主窗口的左側(cè)290px |
| Y | 140 | 控件的最左上角距離主窗口的上方140px |
| Width | 93 | 按鈕的寬度為93px |
| Height | 28 | 按鈕的高度為23px |
而上述的Geometry屬性在.py代碼中是如下體現(xiàn)的:
self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(290, 140, 93, 28)) self.pushButton.setObjectName("pushButton")可以看到,上述代碼的第二行通過setGeometry方法指定了Geometry屬性的四個(gè)值。通過以上的方法,我們可以對(duì)任何一個(gè)控件進(jìn)行布局。
?
?
Qt Designer實(shí)戰(zhàn) -?設(shè)計(jì)一個(gè)計(jì)算器界面
?
使用網(wǎng)格布局(Grid Layout)
首先分析我們的整數(shù)計(jì)算器需要的一些按鈕:
數(shù)字鍵:0-9共10個(gè)。
操作符:+ - * / = CE共6個(gè)
當(dāng)我們?cè)赒t Designer的主窗口中創(chuàng)建上述16個(gè)按鈕之后,按照4行4列的順序進(jìn)行擺放。
并且修改按鈕的屬性中的objectName為相對(duì)于的名稱。如數(shù)字0的objectName設(shè)置為Num_0,操作符+的objectName設(shè)置為OP_plus。對(duì)于按鈕的顯示名稱的修改,在主窗口中雙擊相應(yīng)按鈕則可以快速修改。
由于計(jì)算器中的按鈕是正方形的(我們通常會(huì)選擇正方形),而且不想讓這些按鈕根據(jù)窗口的大小進(jìn)行變化,通過全選16個(gè)按鈕(在主窗口中使用鼠標(biāo)左鍵拖出選擇框,選中16個(gè)按鈕)在右側(cè)找到mininumSize和maximumSize屬性。點(diǎn)擊其左面的箭頭符號(hào)展開選項(xiàng),將其寬和高固定為60。這樣就不會(huì)因?yàn)榭s放窗口而造成按鈕的大小變化了。
在對(duì)所有按鈕完成相應(yīng)操作之后,我們選中16個(gè)按鈕,點(diǎn)擊右鍵,使用網(wǎng)格布局來實(shí)現(xiàn)布局。
?
使用Spacer增加空白間隔
我們?cè)谟?jì)算器上面新建一個(gè)Line Edit用來顯示輸入結(jié)果與計(jì)算結(jié)果。
通過在空白地方右鍵,對(duì)主窗口使用Vertical Lay Out。
此時(shí),我們實(shí)現(xiàn)了一個(gè)計(jì)算器的布局。但顯示框與下面的鍵盤舉例太過近了。這時(shí)我們便需要使用左側(cè)工具箱內(nèi)的Spacer控件。
Spacer顧名思義,分隔器。可以通過以占位的形式來將布局中的不同控件分開部分舉例。
此時(shí),我們拖動(dòng)一個(gè)Vertical Spacer到Line Edit與下面的鍵盤之間。同樣,Horizontal Spacer也可以用來水平地分離控件之間的距離。
雖然Spacer在我們的Qt Designer編輯器中是以藍(lán)色的類似彈簧的外觀存在的,但是在真正的窗體中,Spacer是隱形的。
但這時(shí)的Spacer大小和Line Edit的大小都不是我想要的,而且也無法通過鼠標(biāo)來拖動(dòng)。如果想要改變這些,則需要進(jìn)一步了解這些控件的一些屬性。
?
sizePolicy 尺寸策略
在Qt Designer中,控件的尺寸是可以變化的。每個(gè)控件都擁有sizeHint和minisizeHint兩個(gè)尺寸。其一,sizeHint即尺寸提示;其二,minisizeHint則是最小尺寸。尺寸提示也是控件的期望尺寸,最小尺寸即窗口可以被壓縮到的最小的尺寸。sizePolicy與sizeHint和minisizeHint息息相關(guān)。
對(duì)于布局管理器中的布局無法滿足我們的要求的時(shí)候,sizePolicy屬性便派上了用場。
sizePolicy可以實(shí)現(xiàn)控件的微調(diào)。sizePolicy中共有如下幾種水平和垂直策略。
?
| Fixed | 固定 | 窗口控件具有sizeHint提示的尺寸且尺寸不變 |
| Minimum | 最小 | 窗口控件的sizeHint提示的尺寸即最小尺寸,窗口控件不能比這個(gè)值小,但是可以變大 |
| Maximum | 最大 | 窗口控件的sizeHint提示的尺寸即最大尺寸,窗口控件不能比這個(gè)值大,但是可以壓縮到minisizeHint的尺寸 |
| Preferred | 期望 | 窗口控件的sizeHint提示的尺寸是期望的尺寸,可以壓縮到minisizeHint尺寸,也可以比sizeHint尺寸更大 |
| MinimumExpanding | 最小擴(kuò)展 | 窗口控件的sizeHint提示的尺寸是最小尺寸,不能縮得比這個(gè)尺寸小,但是這個(gè)控件期望可以比這個(gè)尺寸大 |
| Expanding | 擴(kuò)展 | 窗口控件可以縮小到minisizeHint的尺寸,也可以比sizeHint的的尺寸大,但期望是更大 |
| Ignored | 忽略 | 無視窗口控件的sizeHint與minisizeHint,按照默認(rèn)來設(shè)置 |
在sizePolicy的Horizontal Policy和Vertical Policy下面還有Horizontal Stretch和Vertical Stretch兩個(gè)屬性。
讓我們找到Spacer,并修改其屬性的Height為10。
并將其sizeType修改為Fixed固定。此時(shí),觀察左面的計(jì)算器的主界面顯示欄Line Edit與下面的鍵盤之間的間距變小了。
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的PyQT5 之 Qt Designer 介绍与入门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 这个C怎么了?求大佬指教
- 下一篇: 安卓逆向_1 --- 逆向环境配置、AP