数据模型
所有的基于项数据(item data)的数据模型(Model)都是基于QAbstractltemModel类的,这个类定义了视图组件和代理存取数据的接口。数据无需存储在数据模型里,数据可以是其他类、 文件、数据库或任何数据源。Qt中与数据模型相关的几个主要的类的层次结构如图所示。
图中的抽象类是不能直接使用的,需要由子类继承来实现一些纯虚函数。Qt提供了一些模型类用于项数据处理,常见的几个见下表。
数据库相关的3个模型类将在后续数据库编程时专门说明。如果这些现有的模型类无法满足需求,用户可以从QAbstractltemModel、QAbstractListModel或QAbstractTableModel生成自己定制的数据模型类。
视图组件
视图组件(View)就是显示数据模型的数据的界面组件,Qt提供的视图组件如下。
- QListView:用于显示单列的列表数据,适用于一维数据的操作。
- QTreeView:甩于显示树状结构数据,适用于树状结构数据的操作。
- QTableView:用于显示表格状数据,适用于二维表格型数据的操作。
- QColumnView:用多个QListView显示树状层次结构,树状结构的一层用一个QListView显示。
- QHeaderView:提供行表头或列表头的视图组件,如QTableView的行表头和列表头。
视图组件在显示数据时,只需调用视图类的setModel()函数,为视图组件设置一个数据模型,就可以实现视图组件与数据模型之间的关联,在视图组件上的修改将自动保存到关联的数据模型里,一个数据模型可以同时在多个视图组件里显示数据。
用于Model/View结构的几个视图类直接从QAbstractItemView继承而来,而便利类(QListWiget、QTreeWidget和QTableWidget)则从相应的视图类继承而来。视图相关类的层次结构见下图。
视图组件类的数据采用单独的数据模型,视图组件不存储数据。便利类则为组件的每个节点或单元格创建一个项(item),用项存储数据、格式设置等。所以,便利类没有数据模型,它实际上是用项的方式集成了数据模型的功能,这样就将界面与数据绑定了。所以,便利类缺乏对大型数据源进行灵活处理的能力,适用于小型数据的显示和编辑。
代理
代理(Delegate)就是在视图组件上为编辑数据提供编辑器,如在表格组件中编辑一个单元格的数据时,缺省是使用一个QLineEdit编辑框。代理负责从数据模型获取相应的数据,然后显示在编辑器里,修改数据后又将其保存到数据模型中。
QAbstractltemDelegate是所有代理类的基类,作为抽象类,它不能直接使用。它的一个子类QStyledltemDelegate,是Qt的视图组件缺省使用的代理类。
对于一些特殊的数据编辑需求,例如只允许输入整型数,使用一个QSpinBox作为代理组件更恰当,从列表中选择数据时使用QComboBox作为代理组件更好。这时,就可以从QStyledltemDelegate继承创建自定义代理类。