【问题标题】:PyQt5: Using DeleteOnClose when switching to new windowPyQt5:切换到新窗口时使用 DeleteOnClose
【发布时间】:2023-11-22 04:50:02
【问题描述】:

我目前正在 Python 3.7 中创建一个 GUI,在 Spyder 环境中使用 PyQt5 和 Qt Designer。 GUI 有许多不同的窗口。基本上我从 UI_Start 窗口开始,然后在按下按钮时打开下一个窗口。 GUI 工作得很好,但是在大约 50 个窗口之后,程序突然不再显示下一个窗口,但也没有停止执行。这个问题的奇怪之处在于:

  1. 事先已多次调用完全相同的窗口类,但从未出现任何问题
  2. 该问题不仅发生在一个窗口中,也可能发生在另一个窗口类中(但在显示相同数量的窗口之后)

我试图弄清楚为什么 .show() 命令突然不再工作了。我使用打印语句来查看程序“崩溃”的位置。我看到即使 .show() 命令之后的打印语句也在工作,但是由于没有显示窗口,我无法按下任何按钮来触发下一个事件。所以基本上程序挂了。

我对 Python 编程和创建 GUI 比较陌生,但我认为问题可能是由于内存泄漏引起的。这就是为什么我现在尝试在使用 self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True) 关闭窗口时打开内存空间。但是,现在我面临下一个窗口不再出现的问题。那么如果我想在之后显示一个新窗口,我该如何使用 DeleteOnClose 呢?

另外,如果有人对原始问题有任何建议,请告诉我。大约一周后,我一直在尝试找出问题所在,但没有进一步解决。

已经谢谢你了!

我的部分代码可以使用:

class UI_Start(QtWidgets.QMainWindow):
    def __init__(self):
        super(UI_Start, self).__init__() # Call the inherited classes __init__ method
        uic.loadUi('Screen_Start.ui', self) # Load the .ui file
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)   # added newly
        self.Start_pushButton_Start.clicked.connect(self.openKommiScreen)
        
        
    def openKommiScreen(self):
        self.close()
        self.KommiScreen = UI_Kommi(self)  
        
        
class UI_Kommi(QtWidgets.QMainWindow):  
    def __init__(self, parent = None):
        super(UI_Kommi, self).__init__(parent)
        uic.loadUi('Screen_Kommi.ui', self)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
        global sheetNo
        sheetNo = 1
        self.WeiterButton = self.findChild(QtWidgets.QPushButton,'pushButton_Weiter')
        self.WeiterButton.clicked.connect(self.openScanScreen)
        self.show()
        
        
    def openScanScreen(self):
        self.close()
        self.ScanScreen = UI_Scan(self)

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

【问题讨论】:

  • 您说您在打开大约 50 个窗口后遇到了这个问题,但根据您的代码,没有办法实现这一点(因为您总是在显示下一个窗口之前关闭当前窗口);此外,没有与UI_Scan 相关的代码。请始终尝试提供minimal, reproducible example(我们必须能够重现您的问题!)。此外,使用 global 很少是一个好主意。我建议您编辑代码并提供 MRE(仔细阅读上面的链接),因为接受的答案可能不是一个好的解决方案。

标签: python python-3.x pyqt5 spyder


【解决方案1】:

起初我猜这是一个垃圾收集问题。对新窗口的唯一引用存储在上一个窗口中。哪个被删除了,所以不再引用你的窗口对象,python可能会自动删除它。

在这些情况下,我经常使用全局变量来存储当前的 windows 引用。

【讨论】: