Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
191 views
in Technique[技术] by (71.8m points)

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

Suppose we have two windows, one with a button, the parent, and one empty, the child. Codes for parent and child are:

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_())

and 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_())

With this code, when the user clicks the button, the parent is hiden and the child is shown. Now I want to show again the parent when the users closes the child. How can I do this?

question from:https://stackoverflow.com/questions/65940952/open-window-when-clicking-button-hide-parent-and-show-parent-again-when-new-win

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A good solution is to create a custom signal for the child, and emit it when the window is closed.

Note that in order to do that, you have to correctly use pyuic generated files, which is not what you're doing: those files should never, ever be manually modified, as they are only meant for imports and are not intended for further implementation: there are lots of reasons for not doing that, and one of them is that their structure might lead to confusion about the object structure. You can read more about the correct usage of those files in the official PyQt guidelines about using Designer.

Most importantly, since those are simple python object classes (and not Qt widget classes), they don't allow method overriding, which is very important especially in cases like this one.

So, before going on with the example, rebuild those files with pyuic and create a new script for your program.

The concept is that the child class will have a closed signal, and the signal will be emitted within the closeEvent (which is called everytime the window is closed by the user or programmatically with close()); then main window creates the child (but doesn't show it) right in the __init__, and connects its custom signal with that window's 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_())

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...