How to perform action when QCalendarWidget popup closes?
<p>I am using a <code>QDateEdit</code> widget with <code>QDateEdit.setCalendarPopup(True)</code>. I am trying to connect a slot to the event when the calendar popup closes. See my example below for my attempts so far, found in <code>MyCalendarWidget</code>. None of my attempts so far have worked. What can I do to perform an action every time the calendar widget popup closes, <em>not</em> only when the date is changed?</p>

<pre><code>from PyQt4 import QtGui, QtCore
import sys

class MainWindow(QtGui.QMainWindow):
    def __init__(self, *args):
        super(MainWindow,self).__init__(*args)
        self._date = QtGui.QDateEdit()
        self._date.setCalendarPopup(True)
        self._date.setCalendarWidget(MyCalendarWidget())
        self.setCentralWidget(self._date)

class App(QtGui.QApplication):
    def __init__(self, *args):
        super(App,self).__init__(*args)
        self.main = MainWindow()
        self.connect(self, QtCore.SIGNAL("lastWindowClosed()"), self.byebye )
        self.main.show()

    def byebye( self ):
        self.exit(0)

class MyCalendarWidget(QtGui.QCalendarWidget):
    def __init__(self, parent=None):
        print("mycal initialized")
        super(MyCalendarWidget, self).__init__(parent)

        self.installEventFilter(self)
        self._many = 2
        self._many2 = 2

    def focusInEvent(self, event):
        print('-'*self._many + 'focus in')
        if self._many == 2:
            self._many = 4
        else:
            self._many = 2
        super(MyCalendarWidget, self).focusInEvent(event)

    def focusOutEvent(self, event):
        print('-'*self._many2+'focus out')
        if self._many2 == 2:
            self._many2 = 4
        else:
            self._many2 = 2
        super(MyCalendarWidget, self).focusOutEvent(event)

    def closeEvent(self, event):
        print('close')
        super(MyCalendarWidget, self).closeEvent(event)

    def mouseReleaseEvent(self, event):
        print('mouse')
        super(MyCalendarWidget, self).mouseReleaseEvent(event)

def main(args):
    global app
    app = App(args)
    app.exec_()

if __name__ == "__main__":
    main(sys.argv)
</code></pre>

<p>Figured it out - turns out I need to use the <code>clicked</code> signal in <code>QCalendarWidget</code>. This removes the need to sub-class <code>QCalendarWidget</code> as well.</p>

<pre><code>from PyQt4 import QtGui, QtCore
import sys

class MainWindow(QtGui.QMainWindow):
    def __init__(self, *args):
        super(MainWindow,self).__init__(*args)
        self._date = QtGui.QDateEdit()
        self._date.setCalendarPopup(True)
        calendar = self._date.calendarWidget()
        calendar.clicked.connect(self._clicked)
        self.setCentralWidget(self._date)

    def _clicked(self, date):
        print('clicked')

class App(QtGui.QApplication):
    def __init__(self, *args):
        super(App,self).__init__(*args)
        self.main = MainWindow()
        self.connect(self, QtCore.SIGNAL("lastWindowClosed()"), self.byebye )
        self.main.show()

    def byebye( self ):
        self.exit(0)

def main(args):
    global app
    app = App(args)
    app.exec_()

if __name__ == "__main__":
    main(sys.argv)
</code></pre>

python qt qt4 pyqt4