Home > Mobile >  PyQT: Differentiate between close() function and title-bar close [X]
PyQT: Differentiate between close() function and title-bar close [X]

Time:01-26

I have the following function to ask the user if he really wants to quit the window:

def closeEvent(self, event):
    if self.running:
        reply = QMessageBox.question(self, 'QUIT',
                                     'Calculations are currently running!\n'
                                     'Do you really want to quit?',
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()
    else:
        return QMainWindow.closeEvent(self, event)

So when the user presses the red X the QMessageBox will be shown. But I still want to be able to terminate the window without the QMessageBox, for example if I use the close()-function inside the code. Is there a possibility to distinguish between different senders of the CloseEvent like the close()-function or the X-Button?

CodePudding user response:

You can distinguish between system and application events by calling the spontaneous method of the event object. So if the user tries to close the window by clicking the title-bar close button, or by pressing Alt F4, the spontaneous() method will return True.

Here's a simple demo:

from PyQt5 import QtWidgets

class Window(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.button = QtWidgets.QPushButton('Close')
        self.button.clicked.connect(self.close)
        self.check = QtWidgets.QCheckBox('Running')
        self.check.toggled.connect(lambda x: setattr(self, 'running', x))
        self.check.setChecked(True)
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.check)
        layout.addWidget(self.button)

    def closeEvent(self, event):
        if event.spontaneous():
            print('system close event')
            if self.running:
                reply = QtWidgets.QMessageBox.question(
                    self, 'QUIT',
                    'Calculations are currently running!\n'
                    'Do you really want to quit?',
                    QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                    QtWidgets.QMessageBox.No)
                if reply == QtWidgets.QMessageBox.Yes:
                    event.accept()
                else:
                    event.ignore()
        else:
            print('program close event')

if __name__ == '__main__':

    app = QtWidgets.QApplication(['Test'])
    window = Window()
    window.show()
    app.exec_()
  •  Tags:  
  • Related