PyQt和MVC模式
收藏

我正在尝试使用PyQt设计MVC模式。 我想将所有程序分为三个部分:

  1. classes abstracted from all Qt classes (model)
  2. classes providing data from the model to a Qt app (controller)
  3. the Qt app itself with defined method SignalsToSlots that connects signals with controller.

这是最佳选择吗?建议在PyQt开发中使用哪种方案?

最佳答案

您应该做的第一件事是使用Qt4设计器设计gui,并使用pyuic4生成python GUI。这就是您的观点,您永远不要手动编辑这些python文件。始终使用设计器进行更改,以确保您的View与模型和控件分开。

对于控件元素,请创建一个继承自基本gui小部件(例如QMainWindow)的中央类。然后,该对象将包含成员ui,它是您刚生成的视图对象。

这是一个教程中的例子

UPDATE 2013:这是有关PyQt和MVC模型的最新教程 PyQt MVC教程系列

import sys
from PyQt4 import QtCore, QtGui
from edytor import Ui_notepad

class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_notepad()
        self.ui.setupUi(self)


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = StartQT4()
    myapp.show()
    sys.exit(app.exec_())

上例中的关键点是控制器包含ui,并且不直接继承它。控制器将负责管理gui的信号插槽连接,并为您的数据模型提供接口。

为了描述模型部分,我们需要一个示例,假设您的项目是创建电影收藏数据库。该模型将包括代表单个电影的内部对象以及代表电影列表的对象。您可以控制从视图中输入的数据并捕获信号,然后在要求模型更新自身之前对其进行验证。这部分很关键,如果可能的话,控制器不应直接访问模型,而应要求模型进行访问。

这是这种互动的一个小例子(未经测试,可能有一些错别字):

class Movie():
    def __init__(self,title=None,year=None,genre=None):
        self.title=title
        self.year=year
        self.genre=genre
    def update(self,title=None,year=None,genre=None):
        self.title=title
        self.year=year
        self.genre=genre
    def to_xml(self,title=None,date=None,genre=None):
        pass #not implementing this for an example!

#when the controller tries to update it should use update function
movie1.update("Manos Hands Of Fate",1966,"Awesome")
#don't set by direct access, your controller shouldn't get that deep
movie1.title="Bad Idea" #do not want!

在MVC中集中访问也很重要,例如,用户可以通过在屏幕上双击标题或单击标题字段旁边的编辑来更改标题,这两个界面最终都应使用相同的更改方法。因此,我并不是说每个人都叫movie.update_title(title)。我的意思是两个信号在控制器中应使用相同的方法。

尝试尽可能使View与控制器之间的所有关系多对1。这意味着,您有5种方法来更改gui中的某些内容,而在控制器中则有1种方法来处理此问题。如果插槽不是全部兼容,则为每个方法创建方法,然后调用一个方法。如果您为5种视图样式解决了5次问题,那么确实没有理由将视图与控件分开。同样,由于您现在只有一种方法可以在控制器中执行某项操作,因此您在控件和模型之间具有良好的一对一关系。

至于使模型与Qt完全分离,这并不是真正必要的,并且实际上会使您的生活更艰难。在模型中使用诸如QStrings之类的东西可能会很方便,如果在另一个应用程序中,您不需要Gui的开销,但只希望模型仅导入QtCore。希望这会有所帮助!

    公众号
    关注公众号订阅更多技术干货!