第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

时间:2023-03-08 16:17:00
第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

一、概述

在PyQt图形界面中,支持采用Model/View架构实现数据和界面逻辑分离,其中Model用于处理数据存储,View用于界面数据展现,当Model中的数据变化后对应界面视图自动更新,反之当View中数据进行修改之后,也支持通知Model进行数据调整。

为了快速支持Model/View架构,PyQt提供了一系列类来支持,在Qt Designer中Item Views部件栏的视图部件都是用于Model/View架构的View部件,涉及相关的类有QListView、QTableView、QTreeView、QColumnView和QUndoView,通常情况下开发者可以使用这些View类快速构建应用,只有特殊情况下应用才需要实现自己的View类。QAbstractItemView类为以上视图类的基类,也就是直接父类,为所有Model/View架构中的项视图类提供基础功能。

QAbstractItemView类是使用QAbstractItemModel的每个标准视图的基类,它是一个抽象类,它本身不能被实例化。它通过signals和slots机制提供了一个与模型互操作的标准接口,使子类能够随着模型的更改而保持最新。QAbstractItemView类为键盘和鼠标导航、视口滚动、项编辑和选择提供标准支持。

二、Item Views的父类概述

所有view相关的类QListView、QTableView、QTreeView、QColumnView和QUndoView都是从其直接父类QAbstractItemView派生的,而QAbstractItemView又是从其他类派生的,相关类继承关系如下:

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

可以看到,QAbstractItemView的直接父类是QAbstractScrollArea类、QAbstractScrollArea的直接父类是Frame,如此类推,后面依次是QFrame、QWidget、QObejct类。

在Qt Designer内,以上父类中:

本节重点介绍QAbstractItemView类及其父类QFrame、QAbstractScrollArea类。

三、QFrame类属性详解

3.1、概述

QFrame类在视图中主要用于控制视图的框架形状,在Qt Designer中可以设置的属性包括frameShape、framShadow、lineWidth、midLineWidth四个属性。

3.2、frameShape属性

frameShape属性对应类型为QFrame.Shape,该属性表示框架样式中的框架形状,有如下取值:

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

可以通过方法frameShape() 、setFrameShape(Shape)进行属性访问或设置。

3.3、framShadow属性

frameShadow属性对应类型为QFrame.Shadow,该属性表示框架提供三维效果的阴影类型,有如下取值:

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

可以通过frameShadow() 、setFrameShadow(Shadow)进行属性的访问。

3.4、lineWidth和midLineWidth属性

lineWidth和midLineWidth属性用于控制框架线条和中线的宽度,与width、frameWidth这两个属性一起表示框架相关的宽度属性。width是整个QFrame的几何图形的宽度,其他三个用于定义一个Frame的边界的宽度。

为了便于理解这几个属性,我们使用一个案例来图解:

1、案例框架属性设置

我们在Qt Designer中定义一个如下的框架:

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

2、 案例框架生成类的派生类代码

从该图形派生的自定义类构造方法如下:

class w_mainWin(mainWin.Ui_Form,QtWidgets.QWidget):
def __init__(self):
super(w_mainWin, self).__init__()
self.setupUi(self)
str = f"width={self.info.width()},line={self.info.lineWidth()},midline={self.info.midLineWidth()},panelwidth={self.info.frameWidth()} "
self.info.setText(str)
3、案例运行时显示的数据

运行时显示的数据请见下图中心相关数据,对应的属性在框架中使用箭头标记如下:

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

4、 案例结论

可以看到在案例这种设置下,frameWidth = lineWidth*2+midLineWidth

这个结论是否永远正确呢?答案是否。例如在framShape设置为NoFrame时,lineWidth、midLineWidth都可以设置为大于0,但frameWidth 在这种情况下永远为0。因此本例只是用于解释这三者对应Frame各部分的关系。

四、QAbstractScrollArea类属性详解

QAbstractScrollArea是Qt滚动区域的低级抽象,用于控制视图的滚动相关的外观,包括sizeAdjustPolicy、horizontalScrollBarPolicy、verticalScrollB三个属性。除了这三个属性外,还有个与滚动相关的内嵌属性viewport(视口)。

4.1、viewport视口属性

QAbstractScrollArea提供一个称为viewport(视口)的中心小部件,在该小部件中滚动区域的内容可以被滚动展现对应内容,即要展现内容的可见部分在viewport中呈现。

viewport对应的是设备(如屏幕)的物理区域,QAbstractScrollArea本身的窗口对应的是逻辑区域,逻辑区域和物理区域存在映射,缺省这个映射比例是1:1的。如果出现滚动条,则viewport的大小比QAbstractScrollArea大小要减少滚动条对应区域。

老猿理解视口就是视图中呈现展现内容的物理设备如屏幕对应的区域。

QAbstractScrollArea类的视口可以通过方法viewport()来获取。

4.2、horizontalScrollBarPolicy、verticalScrollBarPolicy属性

horizontalScrollBarPolicy、verticalScrollBarPolicy这两个属性是用于控制QAbstractScrollArea滚动条出现机制的,其类型为枚举类型Qt.ScrollBarPolicy,有三种取值,如下:

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

水平滚动条和垂直滚动条是相互独立的,各自设置,相关访问方法为:

horizontalScrollBarPolicy()、setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy)、verticalScrollBarPolicy()、setVerticalScrollBarPolicy(Qt.ScrollBarPolicy)。

4.3、sizeAdjustPolicy属性

这个属性用于在视口(viewport)大小改变时控制滚动区域大小的变化方式,有如下三种取值:

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

五、QAbstractItemView类属性详解

QAbstractItemView类的属性可以分为滚动控制类属性、拖拽类属性、选择类属性、编辑及数据呈现控制属性四大类。

5.1、滚动控制类属性

QAbstractItemView类的滚动控制类属性包括autoScroll、autoScrollMargin、verticalScrollMode和horizontalScrollMode这四个属性。

5.1.1、autoScroll、autoScrollMargin属性

  • autoScroll属性用于确认鼠标在视口边缘时是否自动滚动内容,默认值为True
  • autoScrollMargin属性用于确认视口边缘的范围,默认值为16

由于默认情况下视口和窗口范围相同,当鼠标在视图窗口的autoScrollMargin确认的边缘范围内时,这两个属性用于控制是否自动向对应方向滚动以展示更多的内容。

这两个属性可以通过hasAutoScroll() 、setAutoScroll(bool enable)、autoScrollMargin()、setAutoScrollMargin(int margin)方法去访问这两个属性。

5.1.2、verticalScrollMode和horizontalScrollMode属性

  1. 简介

    verticalScrollMode和horizontalScrollMode属性类型都是枚举类型QAbstractItemView.ScrollMode,用于控制视图如何在垂直方向和水平方向滚动内容。滚动可以按像素或按项目进行。其默认值为通过QStyle.SH_ItemView_ScrollMode指定的样式定义的滚动模式。

  2. QAbstractItemView.ScrollMode类型取值及含义

    第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

  3. 访问方法

    可以通过verticalScrollMode()、horizontalScrollMode() 来读取属性的值,通过setVerticalScrollMode(ScrollMode mode)、setHorizontalScrollMode(ScrollMode mode)、resetHorizontalScrollMode()、resetVerticalScrollMode()来设置属性值,其中reset相关方法是将属性恢复为默认值。

5.2、拖拽类属性

5.2.1、拖拽类属性概述

QAbstractItemView类的拖拽类属性包括dragEnabled、dragDropMode、defaultDropAction、dragDropOverwriteMode、showDropIndicator这五个属性,用于控制拖拽及释放的处理。

5.2.2、dragEnabled属性

dragEnabled属性用于控制视图是否支持拖拽,可以通过dragEnabled()、setDragEnabled(bool enable)进行属性访问和设置。

5.2.3、dragDropMode属性

dragDropMode属性用于控制视图拖放事件的处理方式,其类型为枚举类型DragDropMode。

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

可以通过 dragDropMode()读取属性值,通过setDragDropMode(DragDropMode behavior)设置属性。

5.2.4、defaultDropAction属性

defaultDropAction属性用于控制QAbstractItemView及其子类的实例视图中拖放时放下的默认操作。该属性的类型为枚举类型DropAction。

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

如果未设置该属性,则defaultDropAction默认为CopyAction。可以通过defaultDropAction()、setDefaultDropAction(DropAction)来访问和设置defaultDropAction属性。

5.2.5、dragDropOverwriteMode属性

dragDropOverwriteMode属性用于控制视图的拖放行为,如果其值为True,则视图中选定的数据将在拖拽数据放下时被覆盖,如果其值为False,则拖拽的数据将作为新项插入。当DropAction对应动作为拷贝时,上述拖放的源数据保持不变,而DropAction对应动作为移动数据时,上述拖放的源数据会被删除。

默认值为False,如子类QListView和QTreeView就是这样。而在QTableView子类中,该属性设置为True。

dragDropOverwriteMode() 、setDragDropOverwriteMode(bool overwrite)这两个方法用于访问和设置该属性。

5.2.6、showDropIndicator属性

showDropIndicator属性用于控制在拖拽过程中显示当前拖拽到的位置,当释放时则在当前拖拽位置覆盖或插入。

1、插入模式DropIndicator提示

当鼠标光标移动到两个数据项之间时,拖放指示变成一条横线,表示在当前位置放下数据时将会把数据插入到横线的位置,如图:

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

上图中黄色标记部分的中间细线为拖放指示横线,鼠标光标下面蓝色标记的数据为正在拖放的数据,而下方的蓝色数据是拖放数据来源的数据,即拖放数据是从下方蓝色选中的数据,目前已经拖放到鼠标光标处。当鼠标松开时,数据将在该位置插入,其后面数据往下顺移。

2、替换模式DropIndicator提示

当鼠标光标移动到某个数据项上时,拖放指示变成一长方形边框,表示在当前位置放下数据时将会把数据从该位置开始替换对应大小的数据,如图:

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

上图中黄色标记部分的长方形边框为拖放指示,其他部分同上面图。当鼠标松开时,数据将在该位置覆盖式插入,其自身以及后面等宽数据将被替换。

3、访问方法

showDropIndicator是布尔类型,通过showDropIndicator() 、setDropIndicatorShown(bool enable)可以进行访问。

5.3、选择类属性

QAbstractItemView类的选择类属性包括selectionMode和SelectionBehavior这两个属性。

1、selectionMode属性

electionMode属性用于控制视图的数据选择操作对最终选择结果的影响,其类型为枚举类型QAbstractItemView.SelectionMode,对应取值及含义如下:

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

以上取值中,常用值为SingleSelection 和ExtendedSelection。

selectionMode属性可以通过方法selectionMode()、setSelectionMode(QAbstractItemView.SelectionMode mode)来进行访问或设置。

2、SelectionBehavior属性

SelectionBehavior属性用于控制选择行为操作的数据单位,是指选择时选中数据是按行、按列还是按项来选择。

SelectionBehavior对应类型为枚举类型QAbstractItemView.SelectionBehavior 。对应取值及含义如下:

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

SelectionBehavior属性可以通过方法selectionBehavior()、setSelectionBehavior(QAbstractItemView.SelectionBehavior behavior)来进行访问或设置。

5.4、编辑及数据呈现控制属性

QAbstractItemView类的编辑及数据呈现属性包括editTriggers、tabKeyNavigation、iconSize、textElideMode这四个属性。

1、editTriggers属性

editTriggers属性用于确认哪些用户操作行为会触发ItemView中的数据项进入编辑模式。此属性是由枚举类EditTrigger定义的选择标志集合,多个标志使用或运算符进行组合。只有在用户操作为此属性中设置的操作时,视图中的数据项才会进入编辑模式。

editTriggers属性对应类型为枚举类型EditTrigger,其取值及含义如下:

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

2、tabKeyNavigation属性

tabKeyNavigation属性为bool类型,用于控制视图中是否启用tab键和backtab(shift+tab)进行数据项之间的导航切换。

tabKeyNavigation属性可以使用tabKeyNavigation()、setTabKeyNavigation(bool enable)方法进行属性的访问。

3、iconSize属性

QAbstractItemView的数据根据设置可以显示文字或图标,属性iconSize用于控制显示icon的数据项上的icon图标大小,在视图可见情况下设置该属性会导致视图上的显示项重新调整布局。

可以使用iconSize()返回图标的大小,使用setIconSize(QSize)设置图标的大小。

当调整iconsize时,视图会发射iconSizeChanged(QSize)信号。

4、textElideMode属性

textElideMode属性用于控制省略文本中省略号“…”的位置,当项的内容过多视图无法显示完整时会显示部分内容,并在显示内容中增加省略号以表示项的内容显示不完整。

textElideMode属性的类型为枚举类型 Qt.TextElideMode,缺省值为Qt.ElideRight。

六、小结

本节详细介绍了Model/View架构中视Item Views父类QAbstractItemView、QFrame、QAbstractScrollArea类在Designer中可设置的属性及功能,本部分内容有助于大家详细了解视图类部件的界面属性。

第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

老猿Python,跟老猿学Python!