如何在QMainWindow MVC的closeEvent中从一个非QObject中调用一个方法, PyQt

1 人关注

我正在使用PyQt开发一个基于MVC模型的GUI。所以我有3个文件。

view.py
model.py
controller.py

我想在用户退出GUI时从控制器中执行一个方法,所以当它捕捉到CloseEvent

一个类似的代码看起来是这样的。

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()

当然,ctrl.done()一行并不工作,但它代表了我想做的事情。

我首先在窗口类中实现了它,但我需要从模型文件中获得数据,所以它破坏了MVC模型,因为我没有找到一种方法,使控制器在模型和视图之间用控制器沟通正确的信息。

主要要记住的是,我想让GUI在用户点击exit_msg上的是时发送一个邮件(例子中的方法done())。这个邮件包含来自模型类的数据。我怎么做呢?

你能帮助我吗?

python
python-3.x
model-view-controller
pyqt
pyqt5
Francky380
Francky380
发布于 2019-12-20
1 个回答
eyllanesc
eyllanesc
发布于 2019-12-20
已采纳
0 人赞同

你必须使用一个QObject来监控视图的事件,并相应地实现你想要的逻辑,为此你可以创建另一个继承自QObject的类,并通知控制器,或者控制器是直接监控的QObject,在这种情况下,实现第二个选项

import sys
from PyQt5.QtCore import QEvent, QObject
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
class Window(QMainWindow):
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()