简体   繁体   中英

How to call a method from a non QObject in the closeEvent of QMainWindow MVC PyQt

I am developping a GUI using PyQt based on the MVC model. So I have 3 files:

view.py
model.py
controller.py

I would like to execute a method from the controller when the user quit the GUI, so when it catchs the CloseEvent .

A brief of a similar code looks like this:


from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

import sys

class window(QMainWindow):
    def __init(self):
        super().__init__()

    def closeEvent(self, evnt):
        self.exit_msg = QMessageBox.question(
                self, 'Avant de quitter', 'Would you like to save before leaving ?',
                QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)

        if self.exit_msg == QMessageBox.Yes:
            ctrl.done()
            evnt.accept()
        elif self.exit_msg == QMessageBox.No:
            evnt.accept()
        else:
            evnt.ignore()


class ctrl():
    def __init__(self, view):
        self._view = view

    def done(self):
        print('I sent the mail')

def main():
    app = QApplication(sys.argv)
    view = window()
    view.show()
    controller = ctrl(view = view)

    app.exec()

if __name__ == '__main__':
        main()

Of course the ctrl.done() line does not work but it represents what I would like to do.

I implemented it in the window class in the first place, but I need data from the model file, so it broke the MVC model because I did not find a way to make the controller communicate the right informations between the model and the view using the controller.

The main thing to remember is that I want the GUI to send a mail (method done() in the example) when the user click Yes on the exit_msg . This mail contain data from the model class. How do I do it ?

Can you help me please ?

You have to use a QObject to monitor the events of the view, and accordingly implement the logic you want, and for that you can create another class that inherits from QObject and notifies the Controller, or that the Controller is the QObject that monitors directly, in this case, implement the second option

import sys

from PyQt5.QtCore import QEvent, QObject
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox


class Window(QMainWindow):
    pass


class Controller(QObject):
    def __init__(self, view, parent=None):
        super().__init__(parent)
        self._view = view

        self.view.installEventFilter(self)

    @property
    def view(self):
        return self._view

    def eventFilter(self, obj, event):
        if self.view is obj and event.type() == QEvent.Close:
            exit_msg = QMessageBox.question(
                self.view,
                "Avant de quitter",
                "Would you like to save before leaving ?",
                QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel,
            )
            if exit_msg == QMessageBox.Yes:
                self.done()
            elif exit_msg == QMessageBox.Cancel:
                event.ignore()
                return True
        return super().eventFilter(obj, event)

    def done(self):
        print("I sent the mail")


def main():
    app = QApplication(sys.argv)
    view = Window()
    view.show()
    controller = Controller(view=view)
    app.exec()


if __name__ == "__main__":
    main()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM