PyQt5从子窗口关闭父窗口和子窗口
Posted
技术标签:
【中文标题】PyQt5从子窗口关闭父窗口和子窗口【英文标题】:PyQt5 close Parent window & child window from child window 【发布时间】:2020-08-11 15:14:25 【问题描述】:我已经使用设计器制作了一个 pyqt5 GUI 并转换为 python 代码。 我希望第一个窗口打开另一个窗口,依此类推。
win1->win2->win3
现在我在 win3 中有一个按钮,单击该按钮时必须关闭窗口[win1, win2,win3(itself)] 并且必须再次重新启动win1。
我尝试定义从win1打开win2和从win 2打开win3 两者都没有引发错误,虽然对我没有用
如何做到这一点?请帮帮我。
Win1
from PyQt5 import QtCore, QtGui, QtWidgets
from win_2 import *
class Ui_Win1(object):
def setupUi(self, Win1):
Win1.setObjectName("Win1")
Win1.resize(640, 480)
Win1.setStyleSheet("*background:black;")
self.centralwidget = QtWidgets.QWidget(Win1)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setGeometry(QtCore.QRect(110, 70, 361, 301))
self.frame.setStyleSheet("border: 2px solid white ;\n")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.pushbutton1 = QtWidgets.QPushButton(self.frame)
self.pushbutton1.setGeometry(QtCore.QRect(120, 120, 131, 41))
self.pushbutton1.setStyleSheet("background:white;")
self.pushbutton1.setObjectName("pushbutton1")
Win1.setCentralWidget(self.centralwidget)
self.retranslateUi(Win1)
QtCore.QMetaObject.connectSlotsByName(Win1)
self.pushbutton1.clicked.connect(lambda: self.openwin2()) # calling function
def retranslateUi(self, Win1):
_translate = QtCore.QCoreApplication.translate
Win1.setWindowTitle(_translate("Win1", "MainWindow"))
self.pushbutton1.setText(_translate("Win1", "Go to Win 2"))
def openwin2(self): #Function for opening win2
Win2 = QtWidgets.QMainWindow()
ui = Ui_Win2()
ui.setupUi(Win2)
Win2.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Win1 = QtWidgets.QMainWindow()
ui = Ui_Win1()
ui.setupUi(Win1)
Win1.show()
sys.exit(app.exec_())
Win2
from PyQt5 import QtCore, QtGui, QtWidgets
from win_3 import *
class Ui_Win2(object):
def setupUi(self, Win2):
Win2.setObjectName("Win2")
Win2.resize(640, 480)
Win2.setStyleSheet("*background:black;")
self.centralwidget = QtWidgets.QWidget(Win2)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setGeometry(QtCore.QRect(10, 20, 361, 301))
self.frame.setStyleSheet("border: 2px solid white ;\n")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.pushbutton2 = QtWidgets.QPushButton(self.frame)
self.pushbutton2.setGeometry(QtCore.QRect(120, 120, 131, 41))
self.pushbutton2.setStyleSheet("background:white;")
self.pushbutton2.setObjectName("pushbutton2")
Win2.setCentralWidget(self.centralwidget)
self.retranslateUi(Win2)
QtCore.QMetaObject.connectSlotsByName(Win2)
self.pushbutton2.clicked.connect(self.openwin3) # calling function
def retranslateUi(self, Win2):
_translate = QtCore.QCoreApplication.translate
Win2.setWindowTitle(_translate("Win2", "MainWindow"))
self.pushbutton2.setText(_translate("Win2", "Go to Win 3"))
def openwin3(self): #Function for opening win3
Win3 = QtWidgets.QMainWindow()
ui = Ui_Win3()
ui.setupUi(Win3)
Win3.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Win2 = QtWidgets.QMainWindow()
ui = Ui_Win2()
ui.setupUi(Win2)
Win2.show()
sys.exit(app.exec_())
Win3
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Win3(object):
def setupUi(self, Win3):
Win3.setObjectName("Win3")
Win3.resize(640, 480)
Win3.setStyleSheet("*background:black;")
self.centralwidget = QtWidgets.QWidget(Win3)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setGeometry(QtCore.QRect(250, 140, 361, 301))
self.frame.setStyleSheet("border: 2px solid white ;\n")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.pushbutton3 = QtWidgets.QPushButton(self.frame)
self.pushbutton3.setGeometry(QtCore.QRect(120, 130, 131, 41))
self.pushbutton3.setStyleSheet("background:white;")
self.pushbutton3.setObjectName("pushbutton3")
Win3.setCentralWidget(self.centralwidget)
self.retranslateUi(Win3)
QtCore.QMetaObject.connectSlotsByName(Win3)
def retranslateUi(self, Win3):
_translate = QtCore.QCoreApplication.translate
Win3.setWindowTitle(_translate("Win3", "MainWindow"))
self.pushbutton3.setText(_translate("Win3", "Close and Relaunch"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Win3 = QtWidgets.QMainWindow()
ui = Ui_Win3()
ui.setupUi(Win3)
Win3.show()
sys.exit(app.exec_())
【问题讨论】:
请提供minimal reproducible example 我添加了可重现的示例 【参考方案1】:不要修改 Qt Designer 生成的代码,而是创建另一个继承的类 来自适当的小部件并使用初始类来填充它。
win_1.py
from PyQt5 import QtCore, QtGui, QtWidgets
from win_2 import Ui_Win2 # +++
from win_3 import Ui_Win3 # +++
class Ui_Win1(object):
def setupUi(self, Win1):
Win1.setObjectName("Win1")
Win1.resize(640, 480)
Win1.setStyleSheet("*background:black;")
self.centralwidget = QtWidgets.QWidget(Win1)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setGeometry(QtCore.QRect(110, 70, 361, 301))
self.frame.setStyleSheet("border: 2px solid white ;\n")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.pushbutton1 = QtWidgets.QPushButton(self.frame)
self.pushbutton1.setGeometry(QtCore.QRect(120, 120, 131, 41))
self.pushbutton1.setStyleSheet("background:white;")
self.pushbutton1.setObjectName("pushbutton1")
Win1.setCentralWidget(self.centralwidget)
self.retranslateUi(Win1)
QtCore.QMetaObject.connectSlotsByName(Win1)
def retranslateUi(self, Win1):
_translate = QtCore.QCoreApplication.translate
Win1.setWindowTitle(_translate("Win1", "MainWindow"))
self.pushbutton1.setText(_translate("Win1", "Go to Win 2"))
class Win3(QtWidgets.QMainWindow, Ui_Win3):
def __init__(self, parent=None):
super(Win3, self).__init__(parent)
self.parent = parent
self.setupUi(self)
self.setWindowTitle("Win3")
self.pushbutton3.clicked.connect(self.openwin1)
def openwin1(self): # +++ Function for opening win1
self.parent.show()
self.hide()
class Win2(QtWidgets.QMainWindow, Ui_Win2):
def __init__(self, parent=None):
super(Win2, self).__init__(parent)
self.parent = parent
self.setupUi(self)
self.setWindowTitle("Win2")
self.pushbutton2.clicked.connect(self.openwin3) # calling function
def openwin3(self): # Function for opening win3
self.win3 = Win3(self.parent)
self.win3.show()
self.hide()
class Win1(QtWidgets.QMainWindow, Ui_Win1):
def __init__(self):
super().__init__()
self.setupUi(self)
self.setWindowTitle("Win1")
self.pushbutton1.clicked.connect(self.openwin2) # +++ calling function
def openwin2(self): # Function for opening win2
self.win2 = Win2(self)
self.win2.show()
self.hide()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
win1 = Win1()
win1.show()
sys.exit(app.exec_())
win_2.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Win2(object):
def setupUi(self, Win2):
Win2.setObjectName("Win2")
Win2.resize(640, 480)
Win2.setStyleSheet("*background:black;")
self.centralwidget = QtWidgets.QWidget(Win2)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setGeometry(QtCore.QRect(10, 20, 361, 301))
self.frame.setStyleSheet("border: 2px solid white ;\n")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.pushbutton2 = QtWidgets.QPushButton(self.frame)
self.pushbutton2.setGeometry(QtCore.QRect(120, 120, 131, 41))
self.pushbutton2.setStyleSheet("background:white;")
self.pushbutton2.setObjectName("pushbutton2")
Win2.setCentralWidget(self.centralwidget)
self.retranslateUi(Win2)
QtCore.QMetaObject.connectSlotsByName(Win2)
def retranslateUi(self, Win2):
_translate = QtCore.QCoreApplication.translate
Win2.setWindowTitle(_translate("Win2", "MainWindow"))
self.pushbutton2.setText(_translate("Win2", "Go to Win 3"))
win_3.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Win3(object):
def setupUi(self, Win3):
Win3.setObjectName("Win3")
Win3.resize(640, 480)
Win3.setStyleSheet("*background:black;")
self.centralwidget = QtWidgets.QWidget(Win3)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setGeometry(QtCore.QRect(250, 140, 361, 301))
self.frame.setStyleSheet("border: 2px solid white ;\n")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.pushbutton3 = QtWidgets.QPushButton(self.frame)
self.pushbutton3.setGeometry(QtCore.QRect(120, 130, 131, 41))
self.pushbutton3.setStyleSheet("background:white;")
self.pushbutton3.setObjectName("pushbutton3")
Win3.setCentralWidget(self.centralwidget)
self.retranslateUi(Win3)
QtCore.QMetaObject.connectSlotsByName(Win3)
def retranslateUi(self, Win3):
_translate = QtCore.QCoreApplication.translate
Win3.setWindowTitle(_translate("Win3", "MainWindow"))
self.pushbutton3.setText(_translate("Win3", "Close and Relaunch"))
【讨论】:
以上是关于PyQt5从子窗口关闭父窗口和子窗口的主要内容,如果未能解决你的问题,请参考以下文章
在不关闭子窗口的情况下从子窗口返回焦点到父窗口(在mfc visual studio中)