简短答案
Qt的MVC仅适用于一种数据结构。在谈论MVC 应用程序时,您不应该考虑QAbstractItemModel
或QListView
。
如果您希望整个程序都采用MVC架构,则Qt并不需要这么“庞大”的模型/视图框架。但是对于程序中的每个列表/数据树,您都可以使用Qt MVC方法,该方法的确在视图中包含一个控制器。的数据是内或模型的外部; 这取决于您使用的是哪种类型的模型(自己的模型子类:可能在模型内部;例如QSqlTableModel:在模型外部(但可能在模型内部))。要将模型和视图放在一起,请使用自己的类,然后再实现业务逻辑。
长答案
Qt的模型/视图方法和术语:
Qt 为其模型提供了简单的视图。它们具有内置的控制器:在大多数情况下,控制器会“选择”,选择和移动项目。也就是说,解释用户输入(鼠标单击和移动)并将适当的命令提供给模型。
Qt的模型确实是具有基础数据的模型。当然,抽象模型不会保存数据,因为Qt不知道您要如何存储它们。但是您可以通过将数据容器添加到子类并使模型接口访问数据来扩展QAbstractItemModel以满足您的需求。因此,实际上,并且我认为您不喜欢这种方式,问题在于您需要对模型进行编程,以便了解如何在数据结构中访问和修改数据。
用MVC术语,模型既包含数据又包含逻辑。在Qt中,由您自己决定是否将某些业务逻辑包含在模型中还是将其放置在模型中,取决于您自己。甚至不清楚逻辑的含义:选择,重命名和移动项目?=>已经实现。用它们做计算吗?=>将其放在模型子类的外部或内部。从文件存储数据或将数据加载到文件?=>将其放在模型子类中。
我个人的看法:
这是很难提供良好和一般的MV(C)系统程序员。因为在大多数情况下模型是简单的(例如仅字符串列表),所以Qt还提供了现成的QStringListModel。但是,如果您的数据比字符串还复杂,则取决于您如何通过Qt模型/视图界面表示数据。例如,如果您有一个具有3个字段的结构(例如,具有姓名,年龄和性别的人),则可以将3个字段分配给3个不同的列或3个不同的角色。我不喜欢这两种方法。
我认为Qt的模型/视图框架仅在要显示简单数据结构时才有用。如果数据属于自定义类型或结构不在树或列表(例如图形)中,将变得很难处理。在大多数情况下,列表就足够了,即使在某些情况下,模型也应仅包含一个条目。特别是如果您要为一个具有不同属性的单个条目(一个类的一个实例)建模,则Qt的模型/视图框架不是将逻辑与用户界面分离的正确方法。
综上所述,我认为Qt的模型/视图框架仅在且仅当Qt的查看器小部件之一正在查看您的数据时才有用。如果您要为仅包含一个条目的模型编写自己的查看器(例如,应用程序的设置),或者您的数据不是可打印的类型,则完全没有用。
如何在(更大的)应用程序中使用Qt模型/视图?
我曾经(团队)编写过一个使用多个Qt模型来管理数据的应用程序。我们决定DataRole
为每个不同的模型子类创建一个保存不同类型的实际数据的实际数据。我们创建了一个外部模型类,称为Model
容纳所有不同的Qt模型。我们还创建了一个外部视图类,称为View
保存与之内的模型连接的窗口(窗口小部件)Model
。因此,此方法是扩展的Qt MVC,适合我们自己的需求。无论Model
和View
类本身没有什么关系了Qt MVC。
我们把逻辑放在哪里?我们创建了一些类,它们通过从源模型中读取数据(当它们更改时)并将结果写入目标模型中来对数据进行实际计算。从Qt的角度来看,此逻辑类将是视图,因为它们“连接”到模型(不是用户的“视图”,而是应用程序的业务逻辑部分的“视图”)。
控制器在哪里?在原始MVC术语中,控制器解释用户输入(鼠标和键盘),并向模型发出命令以执行请求的操作。由于Qt视图已经解释了诸如重命名和移动项目之类的用户输入,因此不需要这样做。但是我们需要的是超越Qt视图的用户交互解释。