pythonuser-interfacepyqt5qmainwindowqapplication

Pyqt5 - how to go back to hided Main Window from Secondary Window?


If I click Back from the second window, the program will just exit. How do I go back to mainwindow in this case? I assume I will need some more code in that clickMethodBack function.

import os
import PyQt5
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QWidget, QLabel, QPushButton
import time
from PyQt5.QtCore import QSize

class GUI_Window():
 
    def __init__(self):
        self.main_window()
        return

    def main_window(self):
        app = PyQt5.QtWidgets.QApplication(sys.argv)
        self.MainWindow = MainWindow_()                                                  
        self.MainWindow.show()                                                                    
        app.exec_()                                                                      
        return
                  

class MainWindow_(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)

        self.TestAButton = QPushButton("TestA", self)
        self.TestAButton.clicked.connect(self.TestA_clickMethod)
        self.TestAButton.move(20, 0)

        self.CloseButton = QPushButton("Close", self)
        self.CloseButton.clicked.connect(self.Close_clickMethod)
        self.CloseButton.move(20, 40)

        self.TestingA = TestA_MainWindow()     
    def TestA_clickMethod(self):
        self.TestAButton.setEnabled(False)
        time.sleep(0.2)
        self.TestingA.show()
        self.hide()   

        try:
            if self.TestingA.back == True:
                self.show()
        except:
            None

    def Close_clickMethod(self):
        self.Test_Choice = 'Exit'
        self.close()


class TestA_MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setMinimumSize(QSize(980,700))
        self.setWindowTitle("TestA")

        self.Back_Button = False

        self.closeButton = QPushButton("Close", self)
        self.closeButton.clicked.connect(self.clickMethodClose)

        self.returnButton = QPushButton("Back", self)
        self.returnButton.clicked.connect(self.clickMethodBack)
        self.returnButton.move(0,30)

    def clickMethodClose(self):
        self.Back_Button = False
        self.close()

    def clickMethodBack(self):
        self.returnButton.setEnabled(False)
        time.sleep(0.5)
        self.back = True
        self.close()






# Run if Script
if __name__ == "__main__":
    main = GUI_Window()                                                   # Initialize GUI


Solution

  • Your code has two very important issues.

    1. you're using a blocking function, time.sleep; Qt, as almost any UI toolkit, is event driven, which means that it has to be able to constantly receive and handle events (coming from the system or after user interaction): when something blocks the event queue, it completely freezes the whole program until that block releases control;
    2. you're checking for the variable too soon: even assuming the sleep would work, you cannot know if the window is closed after that sleep timer has ended;

    The solution is to use signals and slots. Since you need to know when the second window has been closed using the "back" button, create a custom signal for the second window that will be emitted whenever the function that is called by the button is closed.

    from PyQt5 import QtCore, QtWidgets
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self):
            super().__init__()
            central = QtWidgets.QWidget()
            layout = QtWidgets.QHBoxLayout(central)
            self.testButton = QtWidgets.QPushButton('Test A')
            self.closeButton = QtWidgets.QPushButton('Close')
            layout.addWidget(self.testButton)
            layout.addWidget(self.closeButton)
            self.setCentralWidget(central)
    
            self.testButton.clicked.connect(self.launchWindow)
            self.closeButton.clicked.connect(self.close)
    
        def launchWindow(self):
            self.test = TestA_MainWindow()
            self.test.backSignal.connect(self.show)
            self.hide()
            self.test.show()
    
    class TestA_MainWindow(QtWidgets.QWidget):
        backSignal = QtCore.pyqtSignal()
        def __init__(self):
            super().__init__()
            layout = QtWidgets.QHBoxLayout(self)
            self.closeButton = QtWidgets.QPushButton('Close')
            self.backButton = QtWidgets.QPushButton('Back')
            layout.addWidget(self.closeButton)
            layout.addWidget(self.backButton)
    
            self.closeButton.clicked.connect(self.close)
            self.backButton.clicked.connect(self.goBack)
    
        def goBack(self):
            self.close()
            self.backSignal.emit()
    
    
    def GUI_Window():
        import sys
        app = QtWidgets.QApplication(sys.argv)
        mainWindow = MainWindow()
        mainWindow.show()
        sys.exit(app.exec_())
    
    
    if __name__ == '__main__':
        GUI_Window()
    

    Notes: