PyQt和MVC模式

alu*_*uuu 30 python qt pyqt

请帮我用PyQt设计MVC模式.我想将所有程序拆分为3个部分:

  1. 从所有Qt类(模型)中抽象出来的一些类
  2. 一些从模型到qt-app(控制器)提供数据的类
  3. Qt-app本身使用定义的方法SignalsToSlots连接信号与控制器.

它是最佳的,并且在PyQt开发中使用了什么方案?

PS:抱歉我的英文=)

cma*_*ard 42

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

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

这是教程中的一个例子

更新2013:这是关于PyQt和MVC Model 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_())
Run Code Online (Sandbox Code Playgroud)

上例中的关键点是控制器包含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!
Run Code Online (Sandbox Code Playgroud)

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

尝试尽可能多地将View和控制器之间的所有关系设置为1.意思是,你有5种方法来改变gui中的某些东西,在控制器中有1个方法来处理这个问题.如果插槽不是所有兼容的,那么为每个方法创建方法,然后调用单个方法.如果您针对5种视图样式解决了5次问题,那么确实没有并且有理由将视图与控件分开.此外,由于您现在只有一种方法可以在控制器中执行某些操作,因此您可以在控件和模型之间建立良好的1对1关系.

至于你的模型与Qt完全分开,这不是真正必要的,实际上可能会让你的生活更加艰难.在你的模型中使用像QStrings这样的东西可能很方便,如果在另一个应用程序中你不想要Gui的开销,但是希望模型只导入QtCore.希望这有帮助!

  • +1,`不要通过直接访问设置,你的控制器不应该那么深`:为什么不提到`self._title=title; self._year=年;...`? (3认同)

abb*_*bot 6

是的,PyQt使用模型/视图概念(官方没有"控制器"部分),但可能你有一些扭曲的图片在PyQt中意味着什么.

有两个部分:

  1. 模型,从适当PyQt的基抽象模型类(子类QAbstractItemModel,QAbstractTableModel,QAbstractListModel等等).这些模型可以直接与您的数据源(文件,数据库)进行通信,也可以代理您之前编写的自己的PyQt无关模型.
  2. 意见,这在Qt库实现,往往不需要任何修改(例如:QTreeView,QTableView和其他人).甚至一些更简单的控件,如QComboBox可以作为PyQt模型的视图.

您应用的所有其他部分(对信号作出反应等)可视为"控制器".

PyQt的还提供了一套可以被继承或直接使用,如果你从模型,如只需要简单的功能,预定义的"通用"模式QStringListModel,QStandardItemModel等等,也有它可以跟数据库中直接,喜欢的模型QSqlTableModel.

  • 请注意,Qt 中的模型/视图框架仅限于递归表(尽管视图主要支持列表、行、表和递归行(树))。如果您的数据具有不同的结构,则可以在不使用 Qt 的 ModelView 框架的 PyQt/Qt 中构建通用 MVC 应用程序。(恕我直言,将东西强行放入 Qt 的 ModelView 并不总是最好的主意......) (2认同)

Jay*_*esh 5

这是关于 Qt 架构如何为应用程序提供模型视图设计的官方详细指南的链接

http://doc.qt.io/qt-5/model-view-programming.html

在 Qt 中,视图和控制器相结合,因此可以使用模型-视图框架来设计应用程序。

该模型与数据源通信,为架构中的其他组件提供接口。通信的性质取决于数据源的类型和模型的实现方式。视图从模型中获取模型索引;这些是对数据项的引用。通过向模型提供模型索引,视图可以从数据源检索数据项。在标准视图中,委托呈现数据项。编辑项目时,委托使用模型索引直接与模型通信。

...

模型、视图和委托使用信号和槽相互通信