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

时间:2018-07-24 20:43:20

标签: python multithreading pyqt pyqt4

我正在将PyQt4与Python 3配合使用。我试图在按下主窗口中的按钮时打开一个对话框窗口。对话窗口还需要能够通过信号将数据发送回主窗口。

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

我已将该帖子用作构建代码的指南。 现在,所有这些都可以正常工作,除非您关闭对话框窗口,然后尝试再次打开它,您将得到:

  

RuntimeError:QDialog类型的包装的C / C ++对象已被删除

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

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

我需要销毁对象(对话框窗口),然后再尝试将其打开。我试图这样做,但是当我只想关闭对话框窗口时,我不确定在不关闭整个应用程序的情况下怎么做。也不确定这是否是解决方案。

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

主窗口:

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)

对话框窗口

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)

任何帮助将不胜感激! :)

1 个答案:

答案 0 :(得分:0)

因此,感谢这篇文章,我解决了这个问题: http://enki-editor.org/2014/08/23/Pyqt_mem_mgmt.html

解决方案是在此处删除此行:

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

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

这里的问题是“ Qt删除了C ++对象,但Python包装器仍然存在”。这似乎是由刚刚删除的那一行引起的。

也许有人可以比我更好地解释它。但这确实解决了问题。