【问题标题】:Hide current QMainWindow when next QMainWindow is called调用下一个 QMainWindow 时隐藏当前 QMainWindow
【发布时间】:2018-04-24 02:30:19
【问题描述】:

我在使用 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”语句没有被执行。

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

【问题讨论】:

  • 什么if声明?除了__main__ 之外,您的代码中没有任何内容
  • @OmarEinea 是的,相同的 if 文件中的 WindowB 语句没有被调用,因此名称 WindowB 没有被初始化,最后 WindowB.hide() 不起作用
  • 然后向我们展示 WindowB 代码
  • @OmarEinea 代码与 WindowA 相同....仍在编辑以供参考

标签: python python-3.x pyqt5


【解决方案1】:

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

您不能在同一个进程中启动两个应用程序,因此您必须选择您希望哪一个成为主窗口,所有其他应用程序都将是辅助窗口(即使它们继承自 QMainWindow)。

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

作为一种好的做法,您可以创建一个主脚本来处理应用程序的初始化并启动一个空的主窗口,然后处理您的工作流程,此外,您可能希望包装您的 UI 类,特别是如果它们是生成的使用 Qt creator,这里是一个例子:

ma​​in.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_())

ma​​in_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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-24
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多