Search code examples
pythoneventspyqt4

PyQt's QMainWindow closeEvent is never called


I'm using pyqt4 in python.
When I close the QMainWindow window , its not handled by closeEvent method. Please someone tell me what is wrong with this code:

from PyQt4 import QtCore, QtGui
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(277, 244)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
    def closeEvent(self,event):
        result = QtGui.QMessageBox.question(self,
                      "Confirm Exit...",
                      "Are you sure you want to exit ?",
                      QtGui.QMessageBox.Yes| QtGui.QMessageBox.No)
        event.ignore()

        if result == QtGui.QMessageBox.Yes:
         event.accept()
if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()

Solution

  • The closeEvent is a method of QMainwindow, but you're trying to use it from your own Ui_MainWindow class. Try this instead:

    from PyQt4 import QtCore, QtGui
    
    
    class MainWindow(QtGui.QMainWindow):
        def __init__(self, *args, **kwargs):
            super(MainWindow, self).__init__(*args, **kwargs)
            self.setupUi()
    
        def setupUi(self):
            self.setObjectName("MainWindow")
            self.resize(277, 244)
            self.statusbar = QtGui.QStatusBar()
            self.statusbar.setObjectName("statusbar")
            self.setStatusBar(self.statusbar)
    
        def closeEvent(self,event):
            result = QtGui.QMessageBox.question(self,
                          "Confirm Exit...",
                          "Are you sure you want to exit ?",
                          QtGui.QMessageBox.Yes| QtGui.QMessageBox.No)
            event.ignore()
    
            if result == QtGui.QMessageBox.Yes:
                event.accept()
    
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        mainWindow = MainWindow()
        mainWindow.show()
        sys.exit(app.exec_())
    

    If you want to keep as much of your structure as possible, try this:

    from PyQt4 import QtCore, QtGui
    
    
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.resize(277, 244)
            self.centralwidget = QtGui.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
            MainWindow.setCentralWidget(self.centralwidget)
            self.statusbar = QtGui.QStatusBar(MainWindow)
            self.statusbar.setObjectName("statusbar")
            MainWindow.setStatusBar(self.statusbar)
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
            MainWindow.show()
    
    
    class MyWindow(QtGui.QMainWindow):
        def closeEvent(self,event):
            result = QtGui.QMessageBox.question(self,
                          "Confirm Exit...",
                          "Are you sure you want to exit ?",
                          QtGui.QMessageBox.Yes| QtGui.QMessageBox.No)
            event.ignore()
    
            if result == QtGui.QMessageBox.Yes:
                event.accept()
    
    
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        MainWindow = MyWindow()
        ui = Ui_MainWindow()
        ui.setupUi(MainWindow)
        sys.exit(app.exec_())