Search code examples
pythonpython-2.7pyqtpyqt4

Closing QWidget window


I am using following code to close Qwidget window automatically after some period of time

class ErrorWindow2(QtGui.QWidget):
    def __init__( self ):
        QtGui.QWidget.__init__( self, None, QtCore.Qt.WindowStaysOnTopHint)

        msgBox = QMessageBox(self)
        msgBox.move (500,500)
        msgBox.setIcon(QMessageBox.Critical)
        msgBox.setText("Test 2")

        msgBox.setWindowTitle("ERROR")
        msgBox.setStandardButtons(QMessageBox.Ok)

        self.errWin2Timer = QtCore.QTimer()
        self.errWin2Timer.timeout.connect(self.closeBox)
        self.errWin2Timer.setSingleShot(True)
        self.errWin2Timer.start(10000)

        ret = msgBox.exec_()

        if ret == QtGui.QMessageBox.Ok:
            return
        else:
            return

    def closeBox(self):
        self.close()

    def closeEvent(self, event):
        logger.debug("Reached Error window 1 close event")
        if self.errWin2:
            self.errWin2.stop()
            self.errWin2.deleteLater()
        event.accept()

But the problem is that self.close doesn't work. What is the best possible way to close the window automatically after some period of time?


Solution

  • The problem is that when you put ret = msgBox.exec_() before the constructor finishes executing, the window object has not finished being built, so there is nothing to close, so when the dialog is closed the window that was just opened will be displayed. I finish building. The idea is to finish building the window and then call ret = msgBox.exec_() and for that we will use a QTimer.singleShot().

    On the other hand, the closeEvent method is not necessary since I was trying to do it. IMHO is to eliminate the self.errWin2Timer from memory (although it seems that there was a typo since you use errWin2 instead of errWin2Timer) but being son of the window is not necessary since in Qt if the parent dies the children will also die.

    from PyQt4 import QtCore,QtGui
    
    class ErrorWindow2(QtGui.QWidget):
        def __init__( self ):
            super(ErrorWindow2, self).__init__(None, QtCore.Qt.WindowStaysOnTopHint)
    
            self.errWin2Timer = QtCore.QTimer(self, 
                interval=10*1000,
                singleShot=True, 
                timeout=self.close)
            self.errWin2Timer.start()
            QtCore.QTimer.singleShot(0, self.showMessageBox)
    
        def showMessageBox(self):
            msgBox = QtGui.QMessageBox(self)
            msgBox.move (500,500)
            msgBox.setIcon(QtGui.QMessageBox.Critical)
            msgBox.setText("Test 2")
            ret = msgBox.exec_()
            if ret == QtGui.QMessageBox.Ok:
                print("OK")
    
    if __name__ == '__main__':
        import sys
        app = QtGui.QApplication(sys.argv)
        w = ErrorWindow2()
        w.show()
        sys.exit(app.exec_())