PyQt多窗口切换
- 理解QApplication
每一个Qt程序都需要有一个QApplication对象,调用*.exec_()方法进入该程序的主循环(即事件循环),事件处理从调用该方法后开始,主循环接受事件消息并将其分发给程序的各个控件,并且程序中不能同时有多个事件循环。 - show()方法
使用show()方法将窗口控件显示在屏幕上。 - 实现多窗口(非对话框形式)
示例程序代码框架如下图所示:
loginView包中含有login界面的控件信息,以及login界面的控制器(即login界面中的业务逻辑),MainWin中包含的文件也是如此。
主程序main.py中主要负责显示窗口,以及绑定与切换窗口有关的信号/槽函数。
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys
from LoginView.login import loginControl
from MainWin.mainWin import MainWinController
class ViewController:
def loadLoginView(self):
self.viewlogin = loginControl() #需要将viewlogin设为成员变量
self.viewlogin.loginSignal.connect(self.loadMainWinView)
self.viewlogin.show()
def loadMainWinView(self, str):
self.viewMainWIn = MainWinController()
self.viewMainWIn.setWindowTitle("MainWin")
self.viewMainWIn.exitSignal.connect(self.loadLoginView) #不需要回到登录界面可以省略
self.viewMainWIn.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
view = ViewController()
view.loadLoginView() #进入登录界面,如果viewlogin不是成员变量,则离开作用域后失效。
sys.exit(app.exec_())
目前来说主程序很简单,但是可以体现出基本的框架。
self.viewlogin = loginControl()
创建一个loginControl()的成员变量,这里需要注意将其作为成员变量,否则在函数调用结束后,就会离开其作用域,该变量就会失效了,就可能会出现运行后一闪而过的现象。
self.viewlogin.loginSignal.connect(self.loadMainWinView)
将登录界面中的登录成功信号绑定到加载主窗口的槽函数loadMianWinView
函数中,用户点击登录按钮后(或者有别的方式执行登录操作时)我们往往还需要进行一些判断的操作等等,当一切准备就绪后,我们就可以在登录窗口发出loginSignal信号,当然也可以在信号中传递一些数据。
self.viewlogin.show()
接下来就是将这个界面显示出来。
两个窗口都在一个事件循环中
下面是login.py的代码:
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from LoginView.loginUI import *
class loginControl(QWidget, Ui_Form):
loginSignal = pyqtSignal(str)
def __init__(self, parent= None):
super(loginControl, self).__init__(parent)
self.setupUi(self)
self.pushButton_enter.clicked.connect(self.btnEnterClicked)
self.pushButton_exit.clicked.connect(self.btnExitClicked)
def btnEnterClicked(self):
print("enter clicked")
#中间可以添加处理逻辑
self.loginSignal.emit("login")
self.close()
def btnExitClicked(self):
print("Exit clicked")
self.close()
这只是demo有别的需要还可以往里面加东西。
下面是mainWin.py的代码:
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from MainWin.mainWinUI import *
class MainWinController(QMainWindow, Ui_MainWindow):
exitSignal = pyqtSignal()
def __init__(self, parent=None):
super(MainWinController, self).__init__(parent)
self.setupUi(self)
self.pushButton_enter.clicked.connect(self.btnEnterClicked)
def btnEnterClicked(self):
print("enter clicked")
def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
print("closed")
self.exitSignal.emit()
self.close()
这同样也只是一个demo。
- 示例代码演示
运行程序后进入登录界面,如下图所示:
点击登录按钮后进入主界面,如下图所示:
关闭主界面后还可以回到登录界面。
源代码
#main.py
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys
from LoginView.login import loginControl
from MainWin.mainWin import MainWinController
class ViewController:
def loadLoginView(self):
self.viewlogin = loginControl()
self.viewlogin.loginSignal.connect(self.loadMainWinView)
self.viewlogin.show()
def loadMainWinView(self, str):
self.viewMainWIn = MainWinController()
self.viewMainWIn.setWindowTitle("MainWin")
self.viewMainWIn.exitSignal.connect(self.loadLoginView)
self.viewMainWIn.show()
print(str)
if __name__ == '__main__':
app = QApplication(sys.argv)
view = ViewController()
view.loadLoginView()
sys.exit(app.exec_())
#login.py
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from LoginView.loginUI import *
class loginControl(QWidget, Ui_Form):
loginSignal = pyqtSignal(str)
def __init__(self, parent= None):
super(loginControl, self).__init__(parent)
self.setupUi(self)
self.pushButton_enter.clicked.connect(self.btnEnterClicked)
self.pushButton_exit.clicked.connect(self.btnExitClicked)
def btnEnterClicked(self):
print("enter clicked")
self.loginSignal.emit("login")
self.close()
def btnExitClicked(self):
print("Exit clicked")
self.close()
#loginUI.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'loginUI.ui'
#
# Created by: PyQt5 UI code generator 5.12.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(400, 300)
self.verticalLayout = QtWidgets.QVBoxLayout(Form)
self.verticalLayout.setObjectName("verticalLayout")
self.label = QtWidgets.QLabel(Form)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
self.label.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setFamily("宋体")
font.setPointSize(14)
self.label.setFont(font)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setVerticalSpacing(30)
self.gridLayout.setObjectName("gridLayout")
self.pushButton_enter = QtWidgets.QPushButton(Form)
self.pushButton_enter.setObjectName("pushButton_enter")
self.gridLayout.addWidget(self.pushButton_enter, 2, 0, 1, 1)
self.lineEdit_2 = QtWidgets.QLineEdit(Form)
self.lineEdit_2.setObjectName("lineEdit_2")
self.gridLayout.addWidget(self.lineEdit_2, 1, 0, 1, 1)
self.lineEdit = QtWidgets.QLineEdit(Form)
self.lineEdit.setObjectName("lineEdit")
self.gridLayout.addWidget(self.lineEdit, 0, 0, 1, 1)
self.pushButton_exit = QtWidgets.QPushButton(Form)
self.pushButton_exit.setObjectName("pushButton_exit")
self.gridLayout.addWidget(self.pushButton_exit, 2, 1, 1, 1)
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 0, 1, 1, 1)
self.label_3 = QtWidgets.QLabel(Form)
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
self.label_3.setObjectName("label_3")
self.gridLayout.addWidget(self.label_3, 1, 1, 1, 1)
self.verticalLayout.addLayout(self.gridLayout)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label.setText(_translate("Form", "欢迎登录"))
self.pushButton_enter.setText(_translate("Form", "登录"))
self.pushButton_exit.setText(_translate("Form", "退出"))
self.label_2.setText(_translate("Form", "TextLabel"))
self.label_3.setText(_translate("Form", "TextLabel"))
#mainWin.py
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from MainWin.mainWinUI import *
class MainWinController(QMainWindow, Ui_MainWindow):
exitSignal = pyqtSignal()
def __init__(self, parent=None):
super(MainWinController, self).__init__(parent)
print("enter")
self.setupUi(self)
self.pushButton_enter.clicked.connect(self.btnEnterClicked)
self.exitSignal.connect(lambda: print("emit"))
def btnEnterClicked(self):
print("enter clicked")
def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
print("closed")
self.exitSignal.emit()
self.close()
#mainWinUI.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'mainWinUI.ui'
#
# Created by: PyQt5 UI code generator 5.12.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(250, 150, 93, 28))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(320, 250, 93, 28))
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_3.setGeometry(QtCore.QRect(180, 300, 93, 28))
self.pushButton_3.setObjectName("pushButton_3")
self.pushButton_enter = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_enter.setGeometry(QtCore.QRect(540, 300, 93, 28))
self.pushButton_enter.setObjectName("pushButton_enter")
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.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
self.pushButton_2.setText(_translate("MainWindow", "PushButton"))
self.pushButton_3.setText(_translate("MainWindow", "PushButton"))
self.pushButton_enter.setText(_translate("MainWindow", "enter"))