I have created a custom QDialog class and overridden the closeEvent to just hide the dialog as it is a child of another widget. My dialog must only close when its parent is closed and not when it’s accepted, rejected or the user clicks the close button.
This all works fine but now I need to open a connection to a database and only close it when the dialog is destroyed not just when it’s closed.
My code:
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_())
Any ideas?
To receive notification when a
QObjectis deleted, connect to itsdestroyed(QObject*)signal.However, in Python, object deletion is less predictable than it is in C++ because objects are garbage collected. For example, see all of the caveats associated with
__del__()in the Python documentation. They may not be deleted when the program exits, which is probably why you’re not receiving the signal.Instead of relying on deletion of the dialog, you could manage the database connection explicitly. In this simple example, you could even use a context manager for slightly nicer code.
Either way, here’s a version of your code that behaves as you expect: https://gist.github.com/3827718
The changes I made were:
Set
app.setQuitOnLastWindowClosedto make sure that the application doesn’t quit when the dialog closes. I presume this is the behavior you want, because otherwise this question doesn’t make sense.Set
Qt.WA_DeleteOnClosetoFalseon the dialog to prevent it from deleting itself when closed. This is preferable to overridingcloseEvent.In
Actually_Close(), the dialog deletes itself (which will also close it). This triggers thedestroyedsignal.With this code, the output is as you expect when you click the button: