PyQt 和 MVC 模式
我正在尝试使用 PyQt 设计 MVC 模式。 我想将所有程序分为 3 部分:
- 从所有 Qt 类(模型)中抽象的类,
- 将模型中的数据提供给 Qt 应用程序(控制器)
- Qt 应用程序本身,具有连接信号的已定义方法
SignalsToSlots
带控制器。
这是最优的吗? PyQt开发推荐使用什么方案?
I am trying to design an MVC-pattern with PyQt.
I want to split all programs into 3 parts:
- classes abstracted from all Qt classes (model)
- classes providing data from the model to a Qt app (controller)
- the Qt app itself with defined method
SignalsToSlots
that connects signals with controller.
Is this optimally? What scheme is recommended for use in PyQt development?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你应该做的第一件事就是使用 Qt4 设计器来设计你的 gui 并使用 pyuic4 来生成你的 python GUI。这将是你的观点,你永远不会手动编辑这些 python 文件。始终使用设计器进行更改,这可确保您的视图与模型和控件分开。
对于控制元素,创建一个继承自基本 gui 小部件(例如 QMainWindow)的中心类。然后,该对象将包含一个成员 ui,它是您刚刚生成的视图对象。
这是教程 2013年更新的示例
:这里是有关 PyQt 和 MVC 模型的最新教程
PyQt MVC 教程系列
上面示例中的关键点是控制器包含ui 并且不直接继承它。控制器将负责管理 GUI 的信号槽连接并为您的数据模型提供接口。
为了描述模型部分,我们需要一个示例,假设您的项目是创建一个电影集合数据库。该模型将包括代表各个电影的内部对象以及代表电影列表的对象。您的控件将从视图中输入数据并捕获信号,然后在要求模型自行更新之前验证它们。这部分至关重要,如果可能的话,控制器不应该直接访问模型,它应该要求模型访问自身。
下面是这种交互的一个小例子(未经测试,可能有一些拼写错误):
在 MVC 中集中访问也很重要,比如用户可以通过在屏幕上双击标题或单击标题旁边的编辑来更改标题字段,这些接口两个最终应该使用相同的方法进行更改。我并不是说每个人都调用 movie.update_title(title)。我的意思是两个信号应该在控制器中使用相同的方法。
尽可能尝试使视图和控制器之间的所有关系为多对一。意思是,您有 5 种方法来更改 gui 中的某些内容,控制器中有 1 种方法来处理此问题。如果插槽并非全部兼容,则为每个方法创建方法,然后调用一个方法。如果您针对 5 种视图样式解决该问题 5 次,那么确实没有理由将视图与控件分开。此外,由于您现在只有一种方法可以在控制器中执行某些操作,因此您在控制和模型之间拥有良好的一对一关系。
至于让您的模型与 Qt 完全分离,这并不是真正必要的,而且实际上可能会让您的生活变得更加困难。在模型中使用 QStrings 之类的东西可能会很方便,如果在另一个应用程序中您不希望 Gui 的开销,但希望模型仅导入 QtCore。希望这有帮助!
One of the first things you should do is use Qt4 designer to design your gui and use pyuic4 to generate your python GUI. This will be your view, you NEVER edit these python files by hand. Always make changes using designer, this ensures your View is separate from your model and control.
For the control element, create a central class that inherits from your base gui widget such as QMainWindow. This object will then contain a member ui that is your view object you just generated.
here is an example from a tutorial
UPDATE 2013: Here is a more recent tutorial(s) on PyQt and MVC Model
PyQt MVC Tutorial Series
The key point in the above example is the controller contains the ui and doesn't inherit it directly. The controller will be responsible for managing signal slots connections for your gui and providing an interface to you data model.
To describe the model part we need an example, lets assume your project is to create a movie collection database. The model would include the internal objects that represent individual movies, along with objects that represent lists of movies. You control would take the data entered from the view and catch the signals, then validate them before asking the model to update itself. That part is crucial, the controller shouldn't directly access the model if at all possible, it should ask the model to access itself.
Here is a small example of this interaction(untested, may be some typos):
It is also important in MVC to centralize access, say the user can change the title by double clicking it on the screen, or by click edit next to the title field, both of those interfaces should end up using the same method for the change. And by this I don't mean each one calls movie.update_title(title). I mean that both signals should use the same method in the controller.
Try as much as possible to make all relationships between the View and the controller many to 1. Meaning, that is you have 5 ways to change something in the gui, have 1 method in the controller to handle this. If the slots aren't all compatible than create methods for each of the methods that then call one single method. If you solve the problem 5 times for 5 view styles then there really isn't and reason to separate the view from the control. Also since you now have only one way to do something in the controller you ahve a nice 1 to 1 relationship between control and model.
As far as having your model completely separate from Qt, that isn't really necessary and may actually make life harder for you. Using things like QStrings in you model can be convenient, and if in another application you don't want the overhead of a Gui but want the models just import QtCore only. Hopefully this helps!
是的,PyQt 使用模型/视图概念(正式没有“控制器”部分),但您可能对 PyQt 中的含义有些扭曲。
有两部分:
QAbstractItemModel
、QAbstractTableModel
、QAbstractListModel
等)子类化。这些模型可以直接与您的数据源(文件、数据库)对话,或者代理您自己之前编写的与 PyQt 无关的模型。QTreeView
、QTableView
等)。即使是一些更简单的控件,例如 QComboBox,也可以充当 PyQt 模型的视图。应用程序中对信号等做出反应的所有其他部分都可以被视为“控制器”。
PyQt 还提供了一组预定义的“通用”模型,如果您只需要模型中的简单功能,例如 QStringListModel、QStandardItemModel 等,则可以对其进行子类化或直接使用。还有一些可以直接与数据库对话的模型,例如QSqlTableModel。
Yes, PyQt uses Model/View concept (officially without the "Controller" part), but may be you have a somewhat distorted picture what does it mean in PyQt.
There are two parts:
QAbstractItemModel
,QAbstractTableModel
,QAbstractListModel
, etc.). These models can talk to your data sources directly (files, databases), or proxy your own PyQt-agnostic models which were written before.QTreeView
,QTableView
and others). Even some simpler controls, likeQComboBox
can act as a view for a PyQt model.All other parts of you application, which react to signals, etc. may be considered as "Controller".
PyQt also provides a set of predefined "universal" models which can be subclassed or used directly if you need only simple functionality from the model, like
QStringListModel
,QStandardItemModel
, etc. And there are also models which can talk to databases directly, likeQSqlTableModel
.以下是关于 Qt 架构如何为应用程序提供模型视图设计的官方详细指南的链接
http://doc.qt.io/qt-5/model-view-programming.html
在Qt中,视图和控制器结合在一起,因此可以使用模型-视图框架来设计应用程序。
...
Here's a link to the official and detailed guide on how Qt architecture offers Model-View design to an application
http://doc.qt.io/qt-5/model-view-programming.html
In Qt, view and controller are combined, therefore an app can be designed using Model-View framework.
...
我通常使用 peewee 来创建模型,这是一个示例:
I usually use peewee to create the model, here is an example: