首页 > 解决方案 > 在pyqt5中管理窗口的正确方法是什么?

问题描述

在我正在构建的应用程序中,我正在使用一些“窗口”。我试图根据 python/行业标准弄清楚如何正确管理它们。我有一个警告屏幕、免责声明屏幕、主 gui 和一个用于传达错误的消息框。

我的客户想要的是显示警告屏幕(QDialog)的程序,然后是单击按钮时的免责声明屏幕(QDialog),然后是用户同意免责声明后的主界面(QMainWindow)。消息框仅在需要提醒用户某些事件时使用。注意:我使用的是 qt desinger

我试图以一种非常面向对象的方式来处理这个项目,但我正在努力以一种不完全混乱的方式来实现它。我打算做的是有一个主类,它在启动时初始化应用程序的所有部分,有两个控制器(一个用于 gui,一个用于后端进程)。

到目前为止,我的 gui 控制器失败得很惨。最初,我为每个窗口创建了一个类,然后尝试在 gui 控制器中为每个窗口创建对象。我被迫将所有类移动到一个文件中,删除 gui 控制器类代码,并利用这个文件作为应用程序的“主”,甚至让第一个窗口启动。我仍然无法在窗口之间切换,最多我可以关闭当前打开的那个。在 Python3/PyQt5 中构建这样的应用程序的正确方法是什么?

一些代码:

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

标签: pythonpyqtpyqt5python-3.6qt-designer

解决方案


一个简单的事实并未显示打开的窗口,局部变量在其范围完成时被删除,在您的情况下window = Disclaimer()是一个将被删除的局部变量,因此可能的解决方案是:

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

虽然更好的选择是创建一个类或函数来实现窗口之间交互的逻辑,但在下面的部分中我将展示一个示例:

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

推荐阅读