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



我创建了一个自定义的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_())

有什么想法吗?

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

然而,在Python中,对象删除的可预测性不如C++中,因为对象是垃圾收集的。例如,请参阅Python文档中与__del__()相关的所有注意事项。当程序退出时,它们可能不会被删除,这可能就是你没有收到信号的原因。

您可以显式管理数据库连接,而不是依赖于对话框的删除。在这个简单的例子中,您甚至可以为稍微好一点的代码使用上下文管理器。


无论哪种方式,这里都有一个代码版本,它的行为与您预期的一样:https://gist.github.com/3827718

我所做的改变是:

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

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

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

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

Connection Opened
Actually Close
Bye bye

相关内容

最新更新