pyqt5 - closing/terminating application
<p>I'm working though the pyqt5 tutorial found here <a href="http://zetcode.com/gui/pyqt5/firstprograms/" rel="noreferrer">Zetcode, PyQt5</a></p>

<p>As an exercise for myself I'm trying to expand on an example so that I am presented with the same dialog message box regardless of method used to close the app:</p>

<ul>
<li>clicking the 'X' button in the title bar (works as intended)</li>
<li>clicking the 'Close' button (produces attribute error)</li>
<li>pressing the 'escape' key (works but not sure how/why)</li>
</ul>

<p>The dialog message box is implemented in the <code>closeEvent</code> method, full script provided at the end.</p>

<p>I'm having two issues:</p>

<p><strong>1. When clicking 'Close' button, instead of just quitting, I want to call <code>closeEvent</code> method including message box dialog.</strong></p>

<p>I have replaced a line of the example code for the 'Close' push button:</p>

<pre><code>btn.clicked.connect(QCoreApplication.instance().quit)
</code></pre>

<p>And instead am trying to call the <code>closeEvent</code> method which already implements the dialog I want:</p>

<pre><code>btn.clicked.connect(self.closeEvent)
</code></pre>

<p>However when i run the script and click the 'Close' button and select the resulting 'Close' option in the dialog i get the following:</p>

<pre><code>Traceback (most recent call last):
File "5-terminator.py", line 41, in closeEvent
    event.accept()
AttributeError: 'bool' object has no attribute 'accept'
Aborted
</code></pre>

<p>Can anyone advise what I'm doing wrong and what needs to be done here?</p>

<p><strong>2. When hitting the escape key somehow the message box dialog is presented and works just fine.</strong></p>

<p>Ok, it's great that it works,  but I'd like to know how and why the message box functionality defined in <code>CloseEvent</code> method is called within the <code>keyPressEvent</code> method.</p>

<p>Full script follows:</p>

<pre><code>import sys
from PyQt5.QtWidgets import (
    QApplication, QWidget, QToolTip, QPushButton, QMessageBox)
from PyQt5.QtCore import QCoreApplication, Qt


class Window(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        btn = QPushButton("Close", self)
        btn.setToolTip("Close Application")
        # btn.clicked.connect(QCoreApplication.instance().quit)
        # instead of above button signal, try to call closeEvent method below
        btn.clicked.connect(self.closeEvent)

        btn.resize(btn.sizeHint())
        btn.move(410, 118)
        self.setGeometry(30, 450, 500, 150)
        self.setWindowTitle("Terminator")
        self.show()

    def closeEvent(self, event):
        """Generate 'question' dialog on clicking 'X' button in title bar.

        Reimplement the closeEvent() event handler to include a 'Question'
        dialog with options on how to proceed - Save, Close, Cancel buttons
        """
        reply = QMessageBox.question(
            self, "Message",
            "Are you sure you want to quit? Any unsaved work will be lost.",
            QMessageBox.Save | QMessageBox.Close | QMessageBox.Cancel,
            QMessageBox.Save)

        if reply == QMessageBox.Close:
            event.accept()
        else:
            event.ignore()

    def keyPressEvent(self, event):
        """Close application from escape key.

        results in QMessageBox dialog from closeEvent, good but how/why?
        """
        if event.key() == Qt.Key_Escape:
            self.close()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    w = Window()
    sys.exit(app.exec_())
</code></pre>

<p>Hope someone can take the time to enlighten me.</p>