简短回答
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视图的用户交互解释。