QWidget实际销毁时执行代码,而不仅仅是关闭

时间:2012-10-02 15:28:46

标签: python qt pyqt destroy

我创建了一个自定义QDialog类并重写了closeEvent以隐藏对话框,因为它是另一个小部件的子代。我的对话框必须仅在其父级关闭时关闭,而不是在被接受,拒绝或用户单击关闭按钮时关闭。

这一切都运行正常,但现在我需要打开一个数据库的连接,只有在对话框被销毁时才关闭它,而不仅仅是在它被关闭时。

我的代码:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys

def Log_Closed():
    print "Bye bye"

class My_dlg(QDialog):
    def __init__(self, parent=None):
        QDialog.__init__( self, parent )

        #self.conn = open_connection()
        print "Connection Opened"

        close_btn  = QPushButton("Actually Close")
        QVBoxLayout(self).addWidget(close_btn)

        close_btn.clicked.connect(self.Actually_Close)
        self.destroyed.connect(Log_Closed)

    def Actually_Close(self):
        print "Actually Close"
        self.parent().close()

    def closeEvent(self, event):
        if event.type() == QEvent.Close:
            event.ignore()
            self.hide()
            print "hidden"

    # And I guess I need something like
    def destroyEvent(self, event):
        #self.conn.close()
        print "Connection Closed"
        event.accept()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main= QMainWindow()
    tsd = My_dlg(main)
    tsd.show()
    sys.exit(app.exec_())

有什么想法吗?

1 个答案:

答案 0 :(得分:8)

要在删除QObject时收到通知,请连接到destroyed(QObject*)信号。

但是,在Python中,对象删除比C ++中的可预测性更低,因为对象是垃圾回收的。例如,请参阅Python documentation中与__del__()相关联的所有警告。程序退出时可能不会删除它们,这可能是您没有收到信号的原因。

您可以显式管理数据库连接,而不是依赖于删除对话框。在这个简单的示例中,您甚至可以使用context manager来获得更好的代码。


无论哪种方式,这里的代码版本都符合您的预期:https://gist.github.com/3827718

我所做的改变是:

  • 设置app.setQuitOnLastWindowClosed以确保在对话框关闭时应用程序不会退出。我认为这是你想要的行为,因为否则这个问题没有意义。

  • 在对话框中将Qt.WA_DeleteOnClose设置为False,以防止它在关闭时自行删除。这比覆盖closeEvent

  • 更可取
  • Actually_Close()中,对话框会自行删除(也会关闭它)。这会触发destroyed信号。

使用此代码,单击按钮时输出正如您所期望的那样:

Connection Opened
Actually Close
Bye bye