[技术博客]Pyqt中View类别容器和Widget类别容器的区别
Pyqt中View类别容器和Widget类别容器的区别
简介
在beta迭代中,我们选择用pyqt5来重写alpha迭代中使用tkinter库编写的界面。
按钮之类的与tkiner使用无异,在显示“测试报告”和“测试队列”这方面,我打算使用列表类控件,但是在qt designer中发现了两个看起来类似的控件:QListView和QListWidget。这两个控件有什么区别呢? 从文档中我得知,QListWidget
是继承自QListView
的,其他Widget容器也是继承自对应View容器,而QListView
是继承自一个抽象基类QAbastractItemView
(python中采用@abstractmethod
实现),三者之间有着以下关系:
但是知道QListView
是QListWidget
的一个子类,只是知道了他们的联系,似乎还是不能直观反映他们的区别。
我们能从网上找到一个不错的解释:
QListView 里没有自己的"模型"要自己建模来保存数据,这可以很大程度上降低数据冗余,提高程序的效率.但是要求我们对view/model框架比较了解,不适合新手使用.
QListWidget是QListView的子类,在QListWidget中已经帮我们定义好了一个模型.这个模型非常方便,十分全面.这样就可以直接在QListWidget里面添加数据,而不用在从新制定一个模型了.十分方便.其实QListView和QListWidget的主要区别就是有木有自己的模型而已.
View类别容器和Widget类别容易主要区别就在于“模型”。那么什么是模型呢?模型是将数据从视图中分离出来的产物,提供和数据交互的接口。Widget类型容器内置了一个简单的模型,我们可以直接调用实例的addItem()
、addItems()
方法来给Widget添加元素,相应变化会直接反映到界面上。而View类别采用了所谓的view/model框架,对视图和数据进行了分离、解耦。Widget部件并没有被设计为可以从视图中分离数据。View类型和Widgt类型看起来相同,但它们与数据的交互方式不同。
view/model框架
view/model框架是qt在qt4以后的版本中用来处理数据和面向用户的最终显示的之间的关系,这种架构也允许使用不同界面显示同一数据,也能够在不改变数据的情况下添加新的显示界面,而这是普通的widget类控件做不到的。除了view和model以外,qt还引入了委托(delegate),用来自定义数据项的渲染和编辑。三者的关系如下:
由于我们组项目目前阶段数据的展示较为简单,选择了相对易用的QListWidget
作为显示数据的方式,因此还未对view/model框架和委托有较为深入的研究。
模型
所有的模型都是QAbstractItemModel
的子类。这个类定义了供视图和委托访问数据的接口。模型并不存储数据本身。这意味着可以将数据存储在一个数据结构中、另外的类中、文件中、数据库中,或者其他所能想到的东西中。
QAbstractItemModel
提供的接口足够灵活,足以应付以表格、列表和树的形式显示的数据。但是,如果需要为列表或者表格设计另外的模型,直接继承QAbstractListModel
和QAbstractTableModel
类可能更好一些,因为这两个类已经实现了很多通用函数。
Qt 内置了许多标准模型:
QStringListModel
:存储简单的字符串列表。QStandardItemModel
:可以用于树结构的存储,提供了层次数据。QFileSystemModel
:本地系统的文件和目录信息。QSqlQueryModel
、QSqlTableModel
和QSqlRelationalTableModel
:存取数据库数据。
如果这些标准模型不能满足需要,就必须继承QAbstractItemModel
、QAbstractListModel
或者QAbstractTableModel
,创建自己的模型类。