UI? ?ui_untitled.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(475, 331)
MainWindow.setProperty("menu", "")
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setObjectName("pushButton_2")
self.horizontalLayout_2.addWidget(self.pushButton_2)
self.retranslateUi(MainWindow)
#實(shí)現(xiàn)裝飾器信號與槽,self.pushButton.setObjectName("pushButton")和下面是必須得
QtCore.QMetaObject.connectSlotsByName(MainWindow)
邏輯代碼頁
# ui下的ui_untitled.py....類 Ui_MainWindow
from ui.ui_untitled import *
class winForm(Ui_MainWindow, QMainWindow):
def __init__(self):
super(winForm, self).__init__() # 運(yùn)行父類的構(gòu)造方法
self.setupUi(self) # 傳遞自己
@QtCore.pyqtSlot()
def on_pushButton_clicked(self):
QMessageBox.information(self, "提示", "btn1信息對話框", QMessageBox.Ok | QMessageBox.Cancel)
@QtCore.pyqtSlot()
def on_pushButton_2_clicked(self):
"""
:param self:
"""
QMessageBox.information(self, "提示", "btn2信息對話框", QMessageBox.Ok | QMessageBox.Cancel)
if __name__ == '__main__':
app = QApplication(sys.argv)
ui = winForm() # 創(chuàng)建PyQt設(shè)計的窗體對象
ui.show() # 顯示窗體
sys.exit(app.exec_())
目錄
一、PyCharm+PyQt5的環(huán)境配置
二、使用Qt Designer將界面顯示與業(yè)務(wù)邏輯分離
三、PyQt5工程中的多文件開發(fā)
轉(zhuǎn)自原文鏈接
作為一個使用C++開發(fā)QT五年的“老”程序猿,總覺得使用C++開發(fā)GUI,是一個很費(fèi)時費(fèi)力或者說沒有“錢”途的事情,因?yàn)楝F(xiàn)在有大量的輕量化的編程語言可以做很絢麗的交互界面,所以筆者現(xiàn)在逐漸向Python轉(zhuǎn)移,逐漸使用PyQt5開發(fā)Qt項(xiàng)目,作為一個python新手,請大家多多指教。
一、PyCharm+PyQt5的環(huán)境配置
具體配置可以在網(wǎng)上搜其它帖子,在這里不作過多論述。
個人在使用過程中,有個習(xí)慣,當(dāng)我們新建了xxx.ui文件,然后使用pyuic5生成xxx.py文件的時候,為了更清楚的看出來這個py文件是由ui文件生成的,也為了防止我們修改這個文件,可以在setting中將pyuic5的Arguments配置中改為“$FileName$ -o ui_$FileNameWithoutExtension$.py”,這樣生成的py文件都是加了“ui_”前綴的。
二、使用Qt Designer將界面顯示與業(yè)務(wù)邏輯分離
大部分的教程都是將使用Qt Designer進(jìn)行界面布局和Qt中控件的使用分開來講,講Qt Designer的時候直接在.ui文件生成的.py文件里面進(jìn)行修改,這樣雖然可以理解界面和代碼之間是如何互聯(lián)共通的,但是不方便.ui文件的修改。在講Qt的各種控件的使用的時候,又幾乎全部用代碼在布局界面,這對于初識Qt的新手來說倒還可以,但對于像筆者這種只換語言不換框架的工程師來講,未免有點(diǎn)太拖沓,所以我們直接講將界面顯示與業(yè)務(wù)邏輯分離的方式開發(fā)。
1、例如我新建一個mainpage.ui文件,里面放幾個控件。
2、將mainpage.ui文件轉(zhuǎn)換成ui_mainpage.py文件
當(dāng)然,也可以直接使用命令生成,不過需要配置環(huán)境變量,需要大家自己去配置,“pyuic5 -o ui_mainpage.py mainpage.ui”
生成的mainpage.py文件,其完整代碼如下:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'mainpage.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, QtWidgets
class Ui_MainPage(object):
def setupUi(self, MainPage):
MainPage.setObjectName("MainPage")
MainPage.resize(739, 449)
self.layoutWidget = QtWidgets.QWidget(MainPage)
self.layoutWidget.setGeometry(QtCore.QRect(90, 80, 521, 271))
self.layoutWidget.setObjectName("layoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget)
self.gridLayout.setContentsMargins(8, 8, 8, 8)
self.gridLayout.setObjectName("gridLayout")
self.driveButton = QtWidgets.QPushButton(self.layoutWidget)
font = QtGui.QFont()
font.setPointSize(14)
self.driveButton.setFont(font)
self.driveButton.setObjectName("driveButton")
self.gridLayout.addWidget(self.driveButton, 2, 0, 1, 1)
self.rangingButton = QtWidgets.QPushButton(self.layoutWidget)
font = QtGui.QFont()
font.setPointSize(14)
self.rangingButton.setFont(font)
self.rangingButton.setObjectName("rangingButton")
self.gridLayout.addWidget(self.rangingButton, 1, 0, 1, 1)
self.cameraButton = QtWidgets.QPushButton(self.layoutWidget)
font = QtGui.QFont()
font.setPointSize(14)
self.cameraButton.setFont(font)
self.cameraButton.setObjectName("cameraButton")
self.gridLayout.addWidget(self.cameraButton, 0, 0, 1, 1)
self.retranslateUi(MainPage)
QtCore.QMetaObject.connectSlotsByName(MainPage)
def retranslateUi(self, MainPage):
_translate = QtCore.QCoreApplication.translate
MainPage.setWindowTitle(_translate("MainPage", "小車控制器"))
self.driveButton.setText(_translate("MainPage", "打開電機(jī)驅(qū)動控制界面"))
self.rangingButton.setText(_translate("MainPage", "打開超聲波測距控制界面"))
self.cameraButton.setText(_translate("MainPage", "打開攝像頭控制界面"))
3、新建一個業(yè)務(wù)邏輯文件,我們可以起名叫“call_mainpage.py”,我們可以在這個文件中新建一個MainPageWindow類,讓它繼承由ui文件生成的py文件中的Ui_MainPage類,這樣我們所有的業(yè)務(wù)邏輯處理,都可以在“call_mainpage.py”文件中進(jìn)行,這樣就不管UI文件什么事情了,當(dāng)修改ui文件后,只影響生成的py文件,邏輯處理文件不受影響。
編寫的call_mainpage.py文件,其代碼如下:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from HomePages.ui_mainpage import Ui_MainPage
from PyQt5.QtCore import pyqtSignal,Qt
class MainPageWindow(QWidget,Ui_MainPage):
#定義點(diǎn)擊信號
chooseSignal = pyqtSignal(str)
def __init__(self,parent=None):
super(MainPageWindow, self).__init__(parent)
self.setupUi(self)
self.initUI()
def initUI(self):
self.setLayout(self.gridLayout)
self.cameraButton.clicked.connect(self.showDialog)
self.rangingButton.clicked.connect(self.showDialog)
self.driveButton.clicked.connect(self.showDialog)
def showDialog(self):
sender = self.sender()
if sender == self.cameraButton:
#發(fā)射點(diǎn)擊信號
self.chooseSignal.emit('camera')
elif sender == self.rangingButton:
self.chooseSignal.emit('ranging')
elif sender == self.driveButton:
self.chooseSignal.emit('drive')
4、在MainPageWindow類中,我定義一個chooseSignal信號,用于向外界發(fā)送按鈕點(diǎn)擊信號。
這樣大家可以直接在call_mainpage.py文件中添加程序main入口運(yùn)行了:
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWindow = MainPageWindow()
mainWindow.show()
sys.exit(app.exec_())
不過我暫時沒有在這個文件中添加main入口,因?yàn)槲乙谄渌募袆?chuàng)建main入口,進(jìn)行多文件調(diào)用。
三、PyQt5工程中的多文件開發(fā)
習(xí)慣使用C++開發(fā)Qt工程,都是習(xí)慣多文件分離開發(fā),每個界面一個ui文件,轉(zhuǎn)換后加一個py文件,再加負(fù)責(zé)一個業(yè)務(wù)邏輯的py文件,一共三個文件。例如寫一個四個界面的工程,步驟如下:
1、使用Qt Designer新建四個不同的ui文件,分別為camerapage.ui、drivepage.ui、mainpage.ui、rangingpage.ui
2、使用pyuic5將四個ui文件轉(zhuǎn)換成對應(yīng)的py文件,分別為ui_camerapage.py、ui_drivepage.py、ui_mainpage.py、ui_rangingpage.py
可以將和UI文件相關(guān)的文件放在一個目錄中,方便管理,筆者把它們都放在了HomePages目錄中。
3、創(chuàng)建四個“ui_”文件對應(yīng)的業(yè)務(wù)邏輯文件,分別為call_camerapage.py、call_drivepage.py、call_mainpage.py、call_rangingpage.py
call_camerapage.py文件內(nèi)容如下:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSignal,Qt
from HomePages.ui_camerapage import Ui_CameraPage
class CameraPageWindow(QWidget,Ui_CameraPage):
#聲明信號
returnSignal = pyqtSignal()
def __init__(self,parent=None):
super(CameraPageWindow, self).__init__(parent)
self.setupUi(self)
self.initUI()
def initUI(self):
self.setLayout(self.gridLayout)
self.returnButton.clicked.connect(self.returnSignal)
call_drivepage.py文件內(nèi)容如下:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSignal,Qt
from HomePages.ui_drivepage import Ui_DrivePage
class DrivePageWindow(QWidget,Ui_DrivePage):
# 聲明信號
returnSignal = pyqtSignal()
def __init__(self, parent=None):
super(DrivePageWindow, self).__init__(parent)
self.setupUi(self)
self.initUI()
def initUI(self):
self.setLayout(self.gridLayout)
self.returnButton.clicked.connect(self.returnSignal)
call_rangingpage.py文件內(nèi)容如下:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSignal,Qt
from HomePages.ui_rangingpage import Ui_RangingPage
class RangingPageWindow(QWidget,Ui_RangingPage):
# 聲明信號
returnSignal = pyqtSignal()
def __init__(self, parent=None):
super(RangingPageWindow, self).__init__(parent)
self.setupUi(self)
self.initUI()
def initUI(self):
self.setLayout(self.gridLayout)
self.returnButton.clicked.connect(self.returnSignal)
call_mainpage.py在前面講過了,就不重復(fù)了,其實(shí)每個call_文件的框架都一樣,分別聲明了CameraPageWindow、DrivePageWindow、RangingPageWindow、MainPageWindow四個類,每個類分別繼承自己對應(yīng)的UI類。
4、這時候需要一個總界面,用來整合所有子頁面,并負(fù)責(zé)界面之間的切換等功能,新建一個mainwindow.py文件,內(nèi)容如下:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from call_mainpage import MainPageWindow
from call_camerapage import CameraPageWindow
from call_drivepage import DrivePageWindow
from call_rangingpage import RangingPageWindow
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.resize(480,320)
self.layout = QGridLayout()
self.setLayout(self.layout)
self.Stack = QStackedWidget()
self.layout.addWidget(self.Stack)
self.mainPageUi = MainPageWindow()
self.cameraPageUi = CameraPageWindow()
self.drivePageUi = DrivePageWindow()
self.rangingPageUi = RangingPageWindow()
self.Stack.addWidget(self.mainPageUi)
self.Stack.addWidget(self.cameraPageUi)
self.Stack.addWidget(self.drivePageUi)
self.Stack.addWidget(self.rangingPageUi)
self.mainPageUi.chooseSignal.connect(self.showDialog)
self.cameraPageUi.returnSignal.connect(self.returnDialog)
self.drivePageUi.returnSignal.connect(self.returnDialog)
self.rangingPageUi.returnSignal.connect(self.returnDialog)
def showDialog(self,msg):
print(0)
if msg == 'camera':
self.Stack.setCurrentIndex(1)
print(1)
elif msg == 'ranging':
self.Stack.setCurrentIndex(2)
print(2)
elif msg == 'drive':
self.Stack.setCurrentIndex(3)
print(3)
def returnDialog(self):
self.Stack.setCurrentIndex(0)
我在這里使用了QStackedWidget疊層窗口,將所有子窗口添加進(jìn)來,根據(jù)不同的點(diǎn)擊顯示不同的頁面。
5、最后,需要有一個main入口,我們單獨(dú)再寫一個main.py文件,這也和C++工程比較統(tǒng)一,具體內(nèi)容如下:文章來源:http://www.zghlxwxcb.cn/news/detail-656215.html
from PyQt5.QtWidgets import *
from mainwindow import MainWindow
import sys
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
6、PyQt5的多界面開發(fā)工程的大體框架就完成,現(xiàn)在只需要添加具體的內(nèi)容即可,可以運(yùn)行試一下,注意一定要運(yùn)行main.py文件,如果運(yùn)行其它py文件,只會出現(xiàn)如下提示。文章來源地址http://www.zghlxwxcb.cn/news/detail-656215.html
到了這里,關(guān)于PyQt5實(shí)現(xiàn)多文件調(diào)用以及UI和邏輯分離的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!