单击按钮时打开window,隐藏parent并在关闭新window时再次显示parent pyqt

Open window when clicking button, hide parent and show parent again when new window is closed pyqt

假设我们有两个 windows,一个带有按钮,parent,一个空,child。 parent 和 child 的代码是:

test_parent.py:

from PyQt5 import QtCore, QtGui, QtWidgets
from test_child import Ui_child

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(270, 208)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(90, 90, 89, 25))
        self.pushButton.setObjectName("pushButton")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.pushButton.clicked.connect(self.open_child)        

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))

    def open_child(self):
        self.child = QtWidgets.QMainWindow()
        self.ui = Ui_child()
        self.ui.setupUi(self.child)
        self.child.show()
        MainWindow.hide()

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

和test_child.py:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_child(object):
    def setupUi(self, child):
        child.setObjectName("child")
        child.resize(275, 176)
        self.centralwidget = QtWidgets.QWidget(child)
        self.centralwidget.setObjectName("centralwidget")
        child.setCentralWidget(self.centralwidget)

        self.retranslateUi(child)
        QtCore.QMetaObject.connectSlotsByName(child)

    def retranslateUi(self, child):
        _translate = QtCore.QCoreApplication.translate
        child.setWindowTitle(_translate("MainWindow", "MainWindow"))

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_child()
    ui.setupUi(child)
    child.show()
    sys.exit(app.exec_())

使用此代码,当用户单击按钮时,parent 会隐藏并显示 child。现在我想在用户关闭 child 时再次显示 parent。我该怎么做?


from PyQt5 import QtCore, QtGui, QtWidgets
from test_parent import Ui_MainWindow

class Ui_child(object):
    def setupUi(self, child):
        child.setObjectName("child")
        child.resize(275, 176)
        self.centralwidget = QtWidgets.QWidget(child)
        self.centralwidget.setObjectName("centralwidget")
        child.setCentralWidget(self.centralwidget)

        self.retranslateUi(child)
        QtCore.QMetaObject.connectSlotsByName(child)

    def retranslateUi(self, child):
        _translate = QtCore.QCoreApplication.translate
        child.setWindowTitle(_translate("MainWindow", "MainWindow"))

    def closeEvent(self, event):
        self.parent = Ui_MainWindow()
        self.parent.setupUi(QtWidgets.QMainWindow())
        self.parent.show()
        self.hide()
        
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_child()
    ui.setupUi(child)
    child.show()
    sys.exit(app.exec_())

一个好的解决方案是为 child 创建一个自定义信号,并在 window 关闭时发出它。

请注意,为了做到这一点,您必须正确使用 pyuic 生成的文件,这不是您正在做的:这些文件永远不应该,ever 被手动修改,因为它们仅用于导入并且 not 用于进一步实施:有很多不这样做的原因,其中之一是它们的结构可能会导致对 object 结构的混淆。您可以在有关 using Designer.

的官方 PyQt 指南中阅读有关这些文件的 正确 用法的更多信息

最重要的是,因为它们很简单 python object classes(并且 not Qt widget classes) , 他们不允许方法覆盖,这非常重要,尤其是在这种情况下。

因此,在继续该示例之前,使用 pyuic 重建这些文件并为您的程序创建一个 new 脚本。

概念是 child class 将有一个 closed 信号,信号将在 closeEvent 内发出(每次 window 由用户关闭或以编程方式使用 close());然后 main window 在 __init__ 中创建 child(但不显示),并将其自定义信号与 window 的 show 连接.

from PyQt5 import QtCore, QtGui, QtWidgets
from test_parent import Ui_MainWindow
from test_child import Ui_child

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.pushButton.clicked.connect(self.openChild)

        # create an instance of the child
        self.child = Child()
        # connect its closed signal to show() of this window
        self.child.closed.connect(self.show)

    def openChild(self):
        self.child.show()
        self.hide()


class Child(QtWidgets.QMainWindow, Ui_child):
    closed = QtCore.pyqtSignal()
    def __init__(self):
        super().__init__()
        self.setupUi(self)

    def closeEvent(self, event):
        self.closed.emit()


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())