无法在 PyQt5 中打开多个窗口

Posted

技术标签:

【中文标题】无法在 PyQt5 中打开多个窗口【英文标题】:Can't open multiple windows in PyQt5 【发布时间】:2016-03-30 17:15:04 【问题描述】:

所以我已经使用 PyQt 设计器制作了几个 GUI,我的目标是让它们中的每一个都能够相互链接并让它们能够相互打开。我已经获得了打开主页的启动页面,但是当我单击主页上的相应按钮打开其他页面时,它会使我的程序崩溃。任何有助于解决此问题的帮助将不胜感激。

我的代码如下:

import sys
from PyQt5 import QtGui, QtCore, QtWidgets
from StartupPage import Ui_StartupWindow
from HomePage import Ui_HomeWindow
from FoodPage import Ui_FoodWindow
from ExercisePage import Ui_ExerciseWindow
from ProfilePage import Ui_ProfileWindow

class Startup(QtWidgets.QMainWindow, Ui_StartupWindow):
    def __init__(self, parent=None):
        super(Startup, self).__init__(parent)
        self.setupUi(self)
        self.NewEntryButton.clicked.connect(self.NewButtonHandle)
        self.ContinueButton.clicked.connect(self.ContinueButtonHandle)
        self.HomeP=Home()

    def NewButtonHandle(self):
        self.HomeP.show()

    def ContinueButtonHandle(self):
        self.HomeP.show()

class Home(QtWidgets.QMainWindow, Ui_HomeWindow):
    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.FoodP=Food()
        self.ExerciseP=Exercise()
        self.ProfileP=Profile()
        self.exerciseButton.clicked.connect(self.ExerciseButtonHandle)
        self.foodButton.clicked.connect(self.FoodButtonHandle)
        self.profileButton.clicked.connect(self.ProfileButtonHandle)

    def ExerciseButtonHandle():
        self.ExerciseP.show()

    def FoodButtonHandle():
        self.FoodP.show()

    def ProfileButtonHandle():
        self.ProfileP.show()

class Food(QtWidgets.QMainWindow, Ui_FoodWindow):
    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.setupUi(self)

class Exercise(QtWidgets.QMainWindow, Ui_ExerciseWindow):
    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.setupUi(self)

class Profile(QtWidgets.QMainWindow, Ui_ProfileWindow):
    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.setupUi(self)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = Startup()
    window.show()
    sys.exit(app.exec_())

【问题讨论】:

【参考方案1】:

尝试将 import sys 移至:

if __name__ == '__main__':
    import sys  """<--------------------------here"""
    app = QtWidgets.QApplication(sys.argv)
    window = Startup()
    window.show()
    sys.exit(app.exec_())

尝试检查您导入的其他模块是否如此。

【讨论】:

【参考方案2】:

了解程序崩溃时显示的错误消息可能很有用。

话虽如此,我最近也在摆弄类似的东西,下面似乎工作正常。请注意,它与您所做的大部分相同。

此外,我还想在主(主)窗口的任何子窗口(window1、window2、window3)打开时阻止与主(主)窗口的交互,以强制用户一次专注于一项任务,而不是打开多个windows - 因此 setEnabled() 调用。

self.Window1.setEnabled(True)

在 home.toWindow1() 中需要行,因为 Window1 是 home 的成员,因此由于第一次 setEnabled 调用而与 home 的所有其他成员一起被禁用。

另外,虽然我确实把我的

import sys

在 Volodymyr 建议的 main 方法中,这只是为了整洁。如果导入是第一行代码或 main 方法中的第一行,对 sys 的引用也将解决(范围规则,LEGB),我看不出将它放在任何一个位置会如何导致任何问题(除非它是在文件开头导入的,后来变量 sys 被分配了一个不同的值)。

我也没有看到按照 Bahnzo 的建议从

from HomePage import Ui_HomeWindow

import HomePage

然后稍后将 Ui_HomeWindow 称为 HomePage.Ui_HomeWindow 会有所不同,原因相同 - 唯一的情况是 Ui_homePage 在导入发生之后和在类中使用之前显式分配了一些值定义 - 您可以看到 OP 的代码中不会发生这种情况。

#!/bin/python3

from PyQt5.QtWidgets import QApplication, QMainWindow
from startwindow import Ui_startWindow
from homewindow import Ui_homeWindow
from window1 import Ui_Window1
from window2 import Ui_Window2
from window3 import Ui_Window3


class start(QMainWindow, Ui_startWindow):
    def __init__(self):
        super(start, self).__init__(None)
        self.setupUi(self)
        self.homeButton.clicked.connect(self.toHome)
        self.home = home()

    def toHome(self):
        self.home.show()
        self.hide()

class home(QMainWindow, Ui_homeWindow):
    def __init__(self):
        super(home, self).__init__(None)
        self.setupUi(self)
        self.window1Button.clicked.connect(self.toWindow1)
        self.window2Button.clicked.connect(self.toWindow2)
        self.window3Button.clicked.connect(self.toWindow3)
        self.Window1 = window1(self)
        self.Window2 = window2(self)
        self.Window3 = window3(self)

    def toWindow1(self):
        self.Window1.show()
        self.setEnabled(False)
        self.Window1.setEnabled(True)

    def toWindow2(self):
        self.Window2.show()
        self.setEnabled(False)
        self.Window2.setEnabled(True)

    def toWindow3(self):
        self.Window3.show()
        self.setEnabled(False)
        self.Window3.setEnabled(True)

    def reEnable(self):
        self.setEnabled(True)

class window1(QMainWindow, Ui_Window1):
    def __init__(self, home):
        super(window1, self).__init__(home)
        self.home = home
        self.setupUi(self)
        self.homeButton.clicked.connect(self.toHome)

    def toHome(self):
        self.home.setEnabled(True)
        self.hide()


class window2(QMainWindow, Ui_Window2):
    def __init__(self, home):
        super(window2, self).__init__(home)
        self.home = home
        self.setupUi(self)
        self.homeButton.clicked.connect(self.toHome)

    def toHome(self):
        self.home.setEnabled(True)
        self.hide()

class window3(QMainWindow, Ui_Window3):
    def __init__(self, home):
        super(window3, self).__init__(home)
        self.home = home
        self.setupUi(self)
        self.homeButton.clicked.connect(self.toHome)

    def toHome(self):
        self.home.setEnabled(True)
        self.hide()

【讨论】:

【参考方案3】:

试试这个:

import Homepage                    #import the whole thing

然后:

class Home(QtWidgets.QMainWindow, Homepage.Ui_HomeWindow):
      #import the UI there

【讨论】:

以上是关于无法在 PyQt5 中打开多个窗口的主要内容,如果未能解决你的问题,请参考以下文章

能够在 PyQt5 中一次打开多个对话框的单窗口模式?

在 PyQt5 中打开一个窗口和关闭一个窗口

在子 multiprocessing.Process (Python3) 中打开 PyQt5 窗口

PyQt5,单击按钮后如何打开新窗口

pyqt5打开txt中文文件闪退

为啥在 PyQt5 中打开新窗口时我的应用程序会关闭?