调用下一个QMainWindow时隐藏当前的QMainWindow

时间:2018-04-23 13:18:09

标签: python python-3.x pyqt5

我在使用PyQt5的Python GUI应用程序中有多个窗口。 我需要在单击按钮时隐藏当前窗口并显示下一个窗口。 这从WindowA到WindowB工作正常,但是从WindowB到WindowC时出错。

我知道初始化存在一些问题,因为WindowB中的初始化代码无法访问,但作为PyQt的初学者,我无法找到解决方案。

WindowA代码:

from PyQt5 import QtCore, QtGui, QtWidgets
from WindowB import Ui_forWindowB
class Ui_forWindowA(object):
     def setupUi(self, WindowA):
          # GUI specifications statements here
          self.someButton = QtWidgets.QPushButton(self.centralwidget)
          self.someButton.clicked.connect(self.OpenWindowB)
          # More GUI specifications statements here
     def retranslateUi(self, WindowA):
          # More statements here
     def OpenWindowB(self):
          self.window = QtWidgets.QMainWindow()
          self.ui = Ui_forWindowB()
          self.ui.setupUi(self.window)
          WindowA.hide()
          self.window.show()

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

WindowB代码:

from PyQt5 import QtCore, QtGui, QtWidgets
from WindowB import Ui_forWindowB
class Ui_forWindowB(object):
     def setupUi(self, WindowB):
          # GUI specifications statements here
          self.someButton = QtWidgets.QPushButton(self.centralwidget)
          self.someButton.clicked.connect(self.OpenWindowC)
          # More GUI specifications statements here
     def retranslateUi(self, WindowB):
          # More statements here
     def OpenWindowB(self):
          self.window = QtWidgets.QMainWindow()
          self.ui = Ui_forWindowC()
          self.ui.setupUi(self.window)
          WindowB.hide() # Error here
          self.window.show()

# The below code doesn't get executed when Ui_forWindowB is called from A
if __name__ == "__main__":
     import sys
     app = QtWidgets.QApplication(sys.argv)
     WindowB = QtWidgets.QMainWindow()
     ui = Ui_forWindowB()
     ui.setupUi(WindowB)
     MainWindow.show()
     sys.exit(app.exec_())

从A到B可以正常工作

WindowA.hide() # Works Properly

从WindowB调用WindowC时

WindowB.hide() # Shows error: name 'WindowB' is not defined

我知道初始化没有完成,因为“if”语句没有被执行。

如何让这个工作? 我在这个流程中有更多的窗口要连接

1 个答案:

答案 0 :(得分:0)

当您运行Python脚本时,执行的第一个文件将被分配名称__main__,因此,如果您首先执行WindowA,则块if __name__ == "__main__"内的代码将被执行并且使用WindowA作为主窗口启动应用程序,类似地,如果先执行WindowB脚本,将使用WindowB作为主窗口启动应用程序。

您无法在同一进程中启动两个应用程序,因此您必须选择要作为主窗口的应用程序,所有其他应用程序将成为辅助窗口(即使它们继承自QMainWindow)。

尽管如此,您应该能够从主窗口中的方法实例化新窗口。

作为一个好习惯,您可以创建一个主脚本来处理应用程序的初始化并启动一个空的主窗口,然后处理您的工作流程,您也可以想要包装UI类,特别是如果它们生成使用Qt创建者,这是一个例子:

<强> main.py

import PyQt5

from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication
from views.main_window import MainWindow


class App(QApplication):
    """Main application wrapper, loads and shows the main window"""

    def __init__(self, sys_argv):
        super().__init__(sys_argv)

        # Show main window
        self.main_window = MainWindow()
        self.main_window.show()


if __name__ == '__main__':
    app = App(sys.argv)

    sys.exit(app.exec_())

<强> main_window.py

这是主窗口,它没有做任何事情,只是控制应用程序的工作流程,即加载WindowA,然后加载WindowB等,注意我从Ui_MainWindow继承,通过这样做,您可以将外观与逻辑分开,并使用Qt Creator生成您的UI:

from PyQt5.QtWidgets import QWidget, QMainWindow
from views.window_a import WindowA
from views.window_b import WindowB
from widgets.main_window import Ui_MainWindow

class MainWindow(Ui_MainWindow, QMainWindow):
    """Main application window, handles the workflow of secondary windows"""

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

        self.setupUi(self)

        # start hidden
        self.hide()

        # show window A
        self.window_a = WindowA()
        self.window_a.actionExit.triggered.connect(self.window_a_closed)
        self.window_a.show()


    def window_a_closed(self):
        # Show window B
        self.window_b = WindowB()
        self.window_b.actionExit.triggered.connect(self.window_b_closed)
        self.window_b.show()

    def window_b_closed(self):
        #Close the application if window B is closed
        self.close()

<强> window_a.py

from PyQt5.QtWidgets import QWidget, QMainWindow
from widgets.main_window import Ui_forWindowA

class WindowA(Ui_forWindowA, QMainWindow):
    """Window A"""

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

        self.setupUi(self)

        # Do some stuff

<强> window_b.py

from PyQt5.QtWidgets import QWidget, QMainWindow
from widgets.main_window import Ui_forWindowB

class WindowA(Ui_forWindowB, QMainWindow):
    """Window B"""

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

        self.setupUi(self)

        # Do some stuff

希望能给你一个让你前进的想法。