Robert
Robert

Reputation: 165

PyQt5: How to use closeEvent with a custom message-box

Before I close my main window, I want to do some last operations. I think the closeEvent is the right thing to do that, but the standard QMessageBox does not suit my design, so I want to make my own (and I did). But with the following code, the application closes directly without showing my message-box.

What here is the problem?

def closeEvent(self, event):
    self.messageBox = lastWindow(self)
    self.messageBox.show()
    return super().closeEvent(event)

This is the lastWindow code: (subclass of a pyuic5 generated .ui file):

from PyQt5 import QtCore
from PyQt5.QtGui import QColor
from PyQt5.QtCore import Qt, QPoint 
from PyQt5.QtWidgets import QDialog, QGraphicsDropShadowEffect

from UIs.UI_quit import Ui_Quit

class lastWindow(QDialog, Ui_Quit):
    def __init__(self, parent = None):
        super(lastWindow, self).__init__(parent)
        self.setupUi(self)
        self._parent = parent
        self.setWindowFlag(QtCore.Qt.WindowType.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground)
        self.setAttribute(QtCore.Qt.WidgetAttribute.WA_DeleteOnClose)
        self.shadow = QGraphicsDropShadowEffect(self)
        self.shadow.setBlurRadius(10)
        self.shadow.setXOffset(5)
        self.shadow.setYOffset(5)
        self.shadow.setColor(QColor(0, 0, 0, 80))
        self.mainFrame.setGraphicsEffect(self.shadow)
        self.btn_close.clicked.connect(self.abort)
        self.btn_quit.clicked.connect(self.destroy)
        self.btn_abort.clicked.connect(self.abort)
        self._parent.blur.setEnabled(True)

    def destroy(self):
        self._parent.close()
        self.close()

    def abort(self):
        self._parent.startService()
        self.close()

Upvotes: 1

Views: 807

Answers (1)

ekhumoro
ekhumoro

Reputation: 120578

Use the built-in accept and reject slots to close the dialog, and then use the return value of exec in your closeEvent to decide what to do next:

class lastWindow(QDialog, Ui_Quit):
    ...
    def destroy(self):
        self.accept()

    def abort(self):
        self.reject()
    
class MainWindow(QMainWindow):
    ...
    def closeEvent(self, event):
        dialog = lastWindow(self)
        if dialog.exec() == QDialog.Rejected:
            self.startService()
            event.ignore()

Calling event.ignore() will prevent the window closing; otherwise, the event will be accepted by default and the window will close. Note that, unlike show(), the exec() call blocks (i.e. it waits for user interaction), which explains why your current example doesn't work as you expected.

Upvotes: 1

Related Questions