PyQt4:如何从主 window 重新打开对话框 window

PyQt4: How to reopen dialog window from main window

我将 PyQt4 与 Python 一起使用 3. 当按下主 window 中的按钮时,我试图打开一个对话框 window。对话框 window 还需要能够通过信号将数据发送回主 window。

这里有人问过类似的问题: Open a second window in PyQt

我已经使用那个 post 作为构建我的代码的指南。 现在所有这些都可以正常工作,除非您关闭对话框 window,然后尝试再次打开它,您会得到:

RuntimeError: wrapped C/C++ object of type QDialog has been deleted

意味着您必须重新启动程序才能再次打开它。这不适用于我的特定应用程序。

据我了解:https://www.daniweb.com/programming/software-development/threads/299395/pyqt-how-to-open-and-close-dialog-multiple-times

我需要先销毁对象(对话框 window),然后再尝试再次打开它。我试图这样做,但是当我只想关闭对话框 window 时,我不确定如何在不关闭整个应用程序的情况下做到这一点。也不确定这是否是解决方案。

这是我的代码的摘要版本:

主要window:

from PyQt4 import QtCore, QtGui
#Qt designer generated code here
class Ui_MainWindow(object):

    def setupUi(self, MainWindow):
        #Ui setup stuff here
        #Button 3
        self.pushButton_3 = QtGui.QPushButton(self.centralwidget)
        self.pushButton_3.clicked.connect(self.pressed_3)

        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        #signal from dialog menu
        self.dialog = QtGui.QDialog()
        self.dialog.ui = entry_window_2.Ui_Dialog()
        self.dialog.ui.setupUi(self.dialog)
        self.dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.dialog.ui.sendVals.connect(self.recieved_save_data)

    def pressed_3(self, checked=None):
        self.dialog.exec_()

    def recieved_save_data(self, value):
        print(value)

对话框window

from PyQt4 import QtCore, QtGui
#PyQt generated code here

class Ui_Dialog(QtCore.QObject):
    sendVals = QtCore.pyqtSignal(int)

    def setupUi(self, Dialog):
        #PyQt Ui_setup code here

        self.ok_cancel = QtGui.QDialogButtonBox(Dialog)
        self.ok_cancel.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
        self.ok_cancel.accepted.connect(self.save)

        QtCore.QObject.connect(self.ok_cancel, QtCore.SIGNAL(_fromUtf8("accepted()")), Dialog.accept)
        QtCore.QObject.connect(self.ok_cancel, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def save(self):
        self.sendVals.emit(1212)

如有任何帮助,我们将不胜感激! :)

所以我通过这篇文章解决了这个问题: http://enki-editor.org/2014/08/23/Pyqt_mem_mgmt.html

解决方法是在此处删除这一行:

self.dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)

我不是专家,但据我了解,PyQt 中的每个 C++ class 都有一个 python 包装器 class。作为 python 程序员,您正在与 python 包装器交互,而包装器在后台与 C++ class 交互。

这里的问题是"C++ object is deleted by Qt but Python wrapper still exists"。这似乎是由刚刚删除的那行引起的。

也许有人能解释得比我好。但这确实解决了问题。