简体   繁体   中英

What is the proper way to manage windows in pyqt5?

In the application I am building I have a few "windows" I am working with. I am trying to figure out, according to python/industry standards, how to properly manage them. I have a warning screen, disclaimer screen, main gui, and essentially a message box for communicating errors.

What my customer would like to transpire is the program displaying the warning screen (QDialog), and then the disclaimer screen (QDialog) on button click, then the main gui (QMainWindow) after the user has agreed to the disclaimer. The message box is only used when the user needs to be alerted to some event. Note: I am using qt desinger

I'm trying to approach this project in a very object orient manner, but I'm struggling to implement this in such a way that it isn't a complete mess. What I intended to do was have a main class that initializes all the pieces of the application at startup, with two controllers (one for the gui and one for the backend processes).

So far my gui controller is failing miserably. Initially, I created a class for each of the windows, and then tried creating objects for each in the gui controller. I was forced to move all the classes into a single file, remove the gui controller class code, and utilize this file as the "main" for the application to even get the first window to launch. I am still unable to switch between windows, at best I can close the one that is currently open. What is the proper way to structure an application like this in Python3/PyQt5?

Some code:

#There used to be another class for gui_controller that instantiated all the below (pyqt5 doesn't work this way as I've come to learn)

#Used to be in its own file.
class WarningScreen(QDialog, Ui_SomeWarningScreen):

    def __init__(self, parent=None):
        super(WarningScreen, self).__init__(parent)
        self.setupUi(self)
        self.accept_button_2.clicked.connect(self.acknowledge_warning)

    def acknowledge_warning(self):
        window = Disclaimer()
        window.show()
        self.close()

#Used to be in its own file.
class DisclaimerScreen(QDialog, Ui_UsageDislaimer):

    def __init__(self, parent=None):
        super(DisclaimerScreen, self).__init__(parent)
        self.setupUi(self)

#This was initially in the main class for the application.
if __name__ == "__main__":

    APP = QApplication(sys.argv)

    WINDOW = WarningScreen()

    WINDOW.show()

    sys.exit(APP.exec_())

The open window is not shown by a simple fact, the local variables are deleted when its scope is finished, in your case window = Disclaimer() is a local variable that will be deleted so a possible solution is:

def acknowledge_warning(self):
    self.window = Disclaimer()
    self.window.show()
    self.close()

Although a better option is to create a class or function where the logic of the interaction between windows is implemented, in the following part I show an example:

class WarningScreen(QtWidgets.QDialog, Ui_SomeWarningScreen):
    closed = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(WarningScreen, self).__init__(parent)
        self.setupUi(self)
        self.accept_button_2.clicked.connect(self.close)
        self.accept_button_2.clicked.connect(self.closed)


class DisclaimerScreen(QtWidgets.QDialog, Ui_UsageDislaimer):
    def __init__(self, parent=None):
        super(DisclaimerScreen, self).__init__(parent)
        self.setupUi(self)


class Controller:
    def __init__(self):
        self.warning = WarningScreen()
        self.disclaimer = DisclaimerScreen()

        self.warning.closed.connect(self.disclaimer.show)
        self.warning.show()

if __name__ == "__main__":
    import sys

    APP = QtWidgets.QApplication(sys.argv)
    w = Controller()
    sys.exit(APP.exec_())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM