第15.27节 PyQt(Python+Qt)入门学习:Model/View架构中的便利类QTreeWidget详解

1、引言

树部件(Tree Widget)是Qt Designer中 Item Widgets(Item-Based)部件中提供的一个Model/View便利部件,对应类为QTreeWidget类。html

QTreeWidget类从QTreeView派生(继承关系请参考《PyQt学习随笔:Qt中Model/View相关的主要类及继承关系》),是一个Model/View便利类,提供一个树状管理数据的界面视图,为了快速支持树状视图展现数据,在类内使用了默认内置的树状模型保存数据项,每一个数据项的类型都是QTreeWidgetItem对象。python

不须要Model/View框架灵活性的开发人员能够很容易地使用QTreeWidget类来建立简单的树状分层列表,但使用QTreeView 与标准项目模型相结合则更灵活,由于QTreeView 与标准项目模型容许将数据的存储与其界面呈现分离。web

一个QTreeWidget类对象包括一个界面上显示的部件框架及对应视口(关于视口请参考《PyQt(Python+Qt)学习随笔:QAbstractScrollArea的viewPort(视口)理解》)、头部标题项、数据项等部分组成。数据结构

2、树型部件中的QTreeWidgetItem项

树型部件的项是单独的类对象,这个类就是QTreeWidgetItem,树型部件的项用于保存树型部件显示数据的信息行。一个项对应的信息行能够包含几列数据,每列均可以包含一个文本标签和一个图标。框架

项一般由父项构造,父项能够是QTreeWidget(用于顶级项)对象或QTreeWidgetItem对象(用于树的二层及如下分支项)。
顶级项与树的下层项之间的主要区别在于顶级项没有parent()方法,这个区别可用于区分项之间的差别,而且在从树中插入和移除项时有助于了解项的状况。less

默认状况下,项的状态是可用(enabled)、可选择(selectable)、可选中(checkable)的,而且能够做为拖放操做的源。能够经过使用适当的值调用setFlags()来更改每一个项的标志(关于项的标记请参考《PyQt(Python+Qt)学习随笔:Model中项的标记flags取值及枚举类型Qt.ItemFlag》)。编辑器

2.一、QTreeWidgetItem的构造方法

QTreeWidgetItem的构造方法以下:ide

  • QTreeWidgetItem(type: int = QTreeWidgetItem.Type)
  • QTreeWidgetItem(label:Iterable[str], type: int = QTreeWidgetItem.Type)
  • QTreeWidgetItem(parent:QTreeWidget, type: int = QTreeWidgetItem.Type)
  • QTreeWidgetItem(parent:QTreeWidget, label:Iterable[str], type: int = QTreeWidgetItem.Type)
  • QTreeWidgetItem(parent:QTreeWidget, preceding:QTreeWidgetItem, type: int = QTreeWidgetItem.Type)
  • QTreeWidgetItem(parent:QTreeWidgetItem, type: int = QTreeWidgetItem.Type)
  • QTreeWidgetItem(parent:QTreeWidgetItem, label:Iterable[str], type: int = QTreeWidgetItem.Type)
  • QTreeWidgetItem(parent:QTreeWidgetItem, preceding:QTreeWidgetItem, type: int = QTreeWidgetItem.Type)
  • QTreeWidgetItem(other: QTreeWidgetItem )

以上构造方法能够单独构建项,也能够构建项以后将项插入到对应部件的对应位置。相关参数说明以下:svg

  • type参数用于指定项的类别

其类型为枚举类型QTreeWidgetItem.ItemType,树型部件中的标准QTreeWidgetItem项对应的取值为QTreeWidgetItem.Type(对应整数0),若是开发者须要从QTreeWidgetItem派生自定义项,则须要使用项的Type值大于等于QTreeWidgetItem.UserType(对应整型1000)的值,使用不一样的type值的目的是为了提供给开发者对自定义项进行诸如排序等特殊处理。函数

  • label参数用于指定项的显示文字
    Iterable[str]表示参数类型为迭代类型,其元素必须是str字符串。
  • parent表示项插入到的对应树型部件或上级项节点
  • preceding表示要新建项插入的前一个项,即项插入到parent下的preceding节点后
  • other:表示项从另外一个项复制一个项的数据
    注意项的type和对应的树型部件不会从other复制。

2.二、QTreeWidgetItem的其余重要属性或方法

2.2.一、项操做方法

2.2.1.一、项标记flags相关方法

QTreeWidgetItem项能够经过flags()返回项的标记,返回值类型为类型Qt.ItemFlags,也可经过setFlags(Qt.ItemFlags flags)来设置项的标记,经过设置标记能够确认象是否能够进行选中、是否可编辑、是否可拖拽、是否支持复选框进行复选操做、是否可用等。具体项能够设置的属性能够参考《PyQt(Python+Qt)学习随笔:Model中项的标记flags取值及枚举类型Qt.ItemFlag》的介绍。

2.2.1.二、判断项是否disable方法

项的方法isDisabled()用于判断项是否可用,返回True表示项禁用,返回False可用。

注意:项的disable设置方法只能经过setFlags方法进行。

2.2.1.三、判断项是否首列跨全部列展现

项方法isFirstColumnSpanned()用于返回是否显示时项的第一列数据跨越全部列,为True即只显示第一列数据,且占用全部列的位置,为False则显示全部列数据。

能够调用方法setFirstColumnSpanned(bool span)来改变该属性。

2.2.1.四、项隐藏相关方法

项能够隐藏不显示,经过方法isHidden()判断项是否隐藏,经过setHidden(bool hide)方法设置项是否隐藏。

2.2.1.五、项选中相关方法

若是flag设置项容许选择,则项能够被选中,下图顶层第二项为选中状态:
在这里插入图片描述
项是否选中能够经过项方法isSelected()来判断,要设置项的选中状态能够经过项的setSelected(bool select)方法来设置。

2.2.二、子项、父项相关操做方法

2.2.2.一、追加子项方法

项构建之后,能够经过addChild(QTreeWidgetItem child)方法在该项中的子节点最后加入另外一个项child做为该项的子项,也能够经过addChildren(iter[QTreeWidgetItem] children)将一个迭代类型children中的多个项加入到该项的子项最后。

若是要插入的项原来已经在QTreeWidgetItem对象中,则该项不会重复加入,若是是多项中有部分项已经在QTreeWidgetItem对象中,则这部分项不会重复加入,其余项则能够加入。

2.2.2.二、插入子项方法

除了追加子项到子项列表最后以外,能够经过insertChild(int index,QTreeWidgetItem child)方法在该项中的子项列表的index位置插入child对应项,该位置及其后位置的项自动后移,也能够经过insertChildren(int index, (iter[QTreeWidgetItem] children)将一个迭代类型children中的多个项从index位置开始顺序插入,原位置的项自动后移。

2.2.2.三、项下子项的指示符展现原则childIndicatorPolicy

树型部件中的项下能够有子项,若是存在子项,则父项的节点是否显示展开或折叠子项的提示符由属性childIndicatorPolicy控制。

childIndicatorPolicy属性的类型为枚举类型QTreeWidgetItem.ChildIndicatorPolicy ,对应取值及含义以下:
在这里插入图片描述

childIndicatorPolicy属性默认值为DontShowIndicatorWhenChildless,能够经过childIndicatorPolicy()和setChildIndicatorPolicy(QTreeWidgetItem.ChildIndicatorPolicy policy)来访问。

2.2.2.四、展开子项

若是一个项有子项,能够调用setExpanded(bool expand)方法来展开或折叠其子项,项的子项是否折叠能够经过isExpanded()方法来判断。

2.2.2.五、获取项的父项或子项

能够经过child(int index) 方法获取项的子项列表中序号为index的项,注意index取值从0开始。子项的个数能够经过childCount()方法获取,index的值必须小于子项的个数,不然返回None。

项的父项能够经过parent() 方法返回,但项若是是顶级项,parent()方法返回None,而不是返回对应的QTreeWidget对象,若是要返回项对应的QTreeWidget对象,可用treeWidget()方法,这个方法对顶级项和非顶级项都是同样的。

2.2.2.六、获取子项索引

可经过indexOfChild(QTreeWidgetItem child)方法返回项下子项child的位置索引,索引值从0计数,若是child对应项未在当前项的子项中,则返回-1。

2.2.2.六、removeChild删除子项

removeChild是根据子项对象从项中删除子项,调用方法为removeChild(QTreeWidgetItem child),操做是从项中删除child对应子项,注意该方法无返回,若是对应子项不存在也不报错。

2.2.2.七、takeChild删除并返回子项

removeChild是根据子项对象从项中删除子项,但无返回,takeChild是根据子项的位置索引来删除子项,同时将删除的子项返回。调用方法为:

QTreeWidgetItem takeChild(int index)

若是执行失败,返回None。

2.2.2.八、takeChildren删除全部子项

takeChildren()是将当前项的全部子项都删除,并将全部子项存储到一个列表中返回,若是当前项没有子项,则返回空列表。

2.2.2.九、sortChildren对子项排序

sortChildren是对项的下层子项按指定列的文本进行排序,调用语法:

sortChildren(int column, Qt.SortOrder order)

Qt.SortOrder为枚举类,有两个常量值,分别为:AscendingOrder升序,对应数值为0,DescendingOrder为降序,对应数值为1。

2.2.2.十、获取项对应的树型部件对象

treeWidget()方法返回项所在树型部件对象,若是项没有插入到树型部件中,则返回None。

2.2.三、项中列相关的操做方法

2.2.3.一、项列数columnCount()方法

项的columnCount方法用于返回项中数据的列数,项数据的列数是在项中实际存储的数据列数,当项构造时传入数据或调用setText(int column,str text)方法增长数据时会改变项的列数。

2.2.3.二、项中列数据的访问方法

树型部件QTreeWidget中的QTreeWidgetItem项中能够有多列数据,每列数据能够根据列位置进行访问。项中列数据的访问方式有两种:

  1. 经过data和setData方法
    能够经过项的data(int column, int role) 方法获取项中指定列指定角色的数据,也能够经过setData(int column, int role, QVariant value)方法设置指定列指定角色的数据为value。
  2. 经过text和setText方法
    能够经过项的text(int column) 方法获取项中指定列的数据,也能够经过setText(int column, str value)方法设置指定的数据为value。

2.2.3.三、项中列图标的访问方法

能够经过icon(int column)来访问项中指定列的图标,经过setIcon(int column, QIcon icon)来设置项中指定列的图标。

以下面代码将顶层第一项第5列的图标设置为指定文件:

self.treeWidget.topLevelItem(0).setIcon(4,QtGui.QIcon(r'F:\小图标\动物\动物-025.gif'))

2.2.3.四、项中列的复选状态访问方法

项中每列数据均可以单独设置复选状态,如图顶层第一项第一列设置了复选状态:
在这里插入图片描述
项中列的复选状态能够经过checkState(int column)来获取,若是要改变项中指定列的复选状态能够调用setCheckState(int column,Qt.CheckState state)来实施。

注意:

2.2.3.五、项中列的其余操做方法

项中的列还能够:

  • 经过textAlignment(int column) 、setTextAlignment(int column,int alignment)来操做文本的对齐方式
  • 经过toolTip(int column)、setToolTip(int column, str toolTip)来操做toolTip
  • 经过statusTip(int column)、setStatusTip(int column, str statusTip)来操做statusTip
  • 经过whatsThis(int column)、setWhatsThis(int column, str whatsThis)来操做whatsThis

3、QTreeWidget的属性

3.一、概述

除了从父类继承的属性外,QTreeWidget在Designer中只有一个属性columnCount属性,另外还有个属性在Designer中没有的属性topLevelItemCount。

3.二、columnCount属性

树型部件中的每一个项有一个或多个文字标签或其余装饰符(如图标),这些内容每一个显示为一列。QTreeWidget的columnCount属性用于控制和保存树型部件窗口展现的每项列数,其缺省值为1。在将项添加到树型部件以前,必须使用setColumnCount()设置显示的列数。项的列数能够经过columnCount()函数获取。
下图是在Designer中设置columnCount为3时的截图:
在这里插入图片描述
在上面介绍QTreeWidgetItem的columnCount属性时,说明了QTreeWidgetItem和QTreeWidget的columnCount属性之间的关系,在此再也不重复。

3.三、topLevelItemCount属性

topLevelItemCount属性是一个只读属性,用于保存树型部件中顶层项的个数,能够经过topLevelItemCount()方法获取属性值,缺省值为0。

当树型部件中顶层项的数目变化时,topLevelItemCount自动跟随变化。

4、QTreeWidget的主要方法

树型部件便利类QTreeWidget的主要方法老猿将其概括为五大类,分别是构造方法、项操做访问方法、与项位置相关访问方法、顶层项操做和访问方法和部件头访问操做方法。

4.一、构造方法

QTreeWidget的构造方法很是简单:

QTreeWidget(QWidget parent = None)

parent是父对象,通常设置为QTreeWidget对象部署的窗口部件。

4.二、项操做访问方法

在前面第二部分介绍了树型部件中的项QTreeWidgetItem类的属性和方法,除了项对象自己的操做方法外,在树型部件QTreeWidget类中也提供了项(包括顶层项)的操做访问方法。本部分介绍通用的项操做方法。

4.2.一、当前项操做访问方法

当前项是指当前鼠标和键盘焦点所在项,在项能够进行选择操做时,当前项能够是选中状态,也能够是未选中状态,选中项也不必定是当前项。与当前项相关的方法包括:

4.2.二、当前列访问方法

树型部件的currentColumn()方法返回当前项中获得焦点的列索引值,从0开始。若是没有当前列,则返回-1。

4.2.三、获取选中项的方法

在树型部件根据选择模式的设置,只要选择模式不是NoSelection(关于选择模式继承自QAbstractItemView,请参考《PyQt(Python+Qt)学习随笔:QAbstractItemView的selectionMode属性》),则能够经过操做选中部件中的项。选中的项能够经过方法selectedItems()方法返回,其返回值为一个列表,列表中的每一个元素是一个选中的QTreeWidgetItem项实例。

4.2.四、搜索项

在树型部件中,能够根据文本、搜索列以及匹配模式来搜索知足条件的项,调用语法:

list[QTreeWidgetItem] findItems( str text, Qt.MatchFlags flags, int column = 0)

返回值为全部知足条件的项构成的列表,若是没有找到匹配项,返回空列表。
Qt.MatchFlags的取值及含义请参考《PyQt(Python+Qt)学习随笔:Model/View中的枚举类 Qt.MatchFlag的取值及含义》。

4.2.五、项排序

能够对树型部件QTreeWidget中的项按照指定列进行排序,调用语法:

sortItems(int column, Qt.SortOrder order)

Qt.SortOrder为枚举类,有两个常量值,分别为:AscendingOrder升序,对应数值为0,DescendingOrder为降序,对应数值为1。

4.2.六、项编辑

在树型部件QTreeWidget中,有三种方法触发进行项数据的编辑。

4.2.6.一、editTriggers触发编辑

在《PyQt(Python+Qt)学习随笔:QAbstractItemView的editTriggers属性以及平台编辑键(platform edit key )》介绍了QAbstractItemView能够经过设置editTriggers来触发编辑,而QTreeWidget是QAbstractItemView类派生的,继承了该属性,所以经过设置该属性为非NoEditTriggers的值便可触发编辑。

editTriggers能够在Qt Designer中设置,如图:
在这里插入图片描述
也能够调用setEditTriggers(EditTriggers triggers)来触发,关于EditTriggers 枚举类请参考PyQt(Python+Qt)学习随笔:QAbstractItemView的editTriggers属性以及平台编辑键(platform edit key )》。

4.2.6.二、editItem触发编辑

QTreeWidget提供了进行项编辑的方法editItem,调用语法以下:

editItem(QTreeWidgetItem item, int column = 0)

4.2.6.三、openPersistentEditor打开持久编辑器

上面介绍editItem时说明了editItem只能触发一次编辑,能够说进入临时编辑状态,一旦退出编辑除非再经过相关方式触发编辑不然项不可再编辑。与此相对应,QTreeWidget还提供了一种一旦打开编辑状态就能够随时再次编辑,除非显示关闭编辑状态,这种方式就是打开持久编辑器。调用方法以下:

openPersistentEditor(QTreeWidgetItem item, int column = 0)

该方法没有返回值。

4.2.七、项首列跨全部列展现

在前面介绍了QTreeWidgetItem项的isFirstColumnSpanned()方法,该方法用于返回是否显示时项的第一列数据跨越全部列,并能够调用方法setFirstColumnSpanned(bool span)来改变该属性。

在树型部件QTreeWidget中也有相似方法,分别是isFirstItemColumnSpanned和setFirstItemColumnSpanned,调用方法以下:

  • bool isFirstItemColumnSpanned( QTreeWidgetItem item)
  • setFirstItemColumnSpanned( QTreeWidgetItem item, bool span)

这两个方法与项方法isFirstColumnSpanned、setFirstColumnSpanned的做用彻底相同,就是方法名和参数有所区别,因为是部件方法,参数中必须指定项,而isFirstColumnSpanned、setFirstColumnSpanned自己是项的实例方法,无需指定项。

4.三、顶层项操做访问方法

在4.1部分介绍了树型部件QTreeWidget方法中与项相关的方法,上述方法适用于全部树型部件的项,除了这些方法以外,树型部件QTreeWidget类还提供了部分与顶层项相关的访问和操做方法。

4.3.一、取指定位置顶层项topLevelItem方法

topLevelItem方法根据位置索引取指定位置的顶层项,调用语法以下:
QTreeWidgetItem topLevelItem(int index)

4.3.二、访问QTreeWidget的隐形根节点

该方法严格来讲不属于顶层项的方法,只是只有一个方法且确实能经过它方法顶层项,所以在此仍是归并到顶层项的方法中。

咱们知道在数据结构上来讲,任何树都是有根节点的,但咱们在QTreeWidget对象中并无看到界面上展现一个根节点,在QTreeWidget对象和数据项构建时也没有指定这样的根节点,但实际上这个根节点仍是存在的,只是不可见,且该节点是树型部件建立以后就自动建立,不管是否存在顶层项。

QTreeWidget提供了访问该隐形根节点的方法,调用语法以下:

QTreeWidgetItem invisibleRootItem()

这个方法其实用途不大,主要是能够用于递归访问树的全部节点,递归不是从topLevelItem开始,而是从根节点开始,全部节点的类型都是QTreeWidgetItem ,能够用QTreeWidgetItem 的child方法逐层递归访问。

4.3.三、给QTreeWidget增长顶层项的方法

QTreeWidget对象建立后,是没有任何项的,要给部件增长项,首先要增长顶层项。顶层项的增长有三类方法,一类是在前面介绍的QTreeWidgetItem中的构造方法构造项时,直接将QTreeWidget对象做为参数传递进去;第二类是利用上面介绍的隐形根节点,在隐形根节点下面调用QTreeWidgetItem相关方法增长子项便可;第三类就是直接调用QTreeWidget相关方法。

4.3.3.一、追加顶层项的方法

树型部件构建之后,能够经过addTopLevelItem(QTreeWidgetItem item)方法在部件中顶层项的最后加入另外一个项item项的顶层项,也能够经过addTopLevelItems(iter[QTreeWidgetItem] items)将一个迭代类型items中的多个项加入到顶层项的最后。

若是要插入的项原来已经在QTreeWidget的项中,则该项不会重复加入,若是是多项中有部分项已经在QTreeWidget的项中,则这部分项不会重复加入,其余项则能够加入。

4.3.3.二、插入顶层项方法

除了追加顶层项到顶层项最后以外,能够经过insertTopLevelItem(int index,QTreeWidgetItem item)方法在部件中顶层项列表的index位置插入item对应项,该位置及其后位置的项自动后移,也能够经过insertTopLevelItems(int index, (iter[QTreeWidgetItem] items)将一个迭代类型items中的多个项从index位置开始顺序插入,原位置的项自动后移。

4.3.四、获取顶层项位置的indexOfTopLevelItem方法

经过调用树型部件的indexOfTopLevelItem方法能够得到对应项在顶层项的位置,调用语法以下:

int indexOfTopLevelItem(QTreeWidgetItem item)
若是对应项未在顶层项中,则返回-1。

4.3.五、删除指定位置的顶层项takeTopLevelItem方法

树型部件的takeTopLevelItem方法能够从树型部件中删除对应项的节点并返回该项,调用语法以下:

QTreeWidgetItem takeTopLevelItem(int index)
若是对应位置无顶层项,则返回None。

4.四、与项位置相关的方法

4.4.一、项的上项和下项

项在树型部件中展现时,其界面上面的项称为上项,其界面下面的项称为下项,上项和下项与项不必定是同一层级的。以下图:
在这里插入图片描述
上图中蓝色选中的项(d:\)是当前项,其上项为黄色标记的项(c:\Python),其下项是蓝色框标记的项(d:\work)。这在Qt文档中是没有说明的,老猿是通过验证确认的,具体验证过程请参考《PyQt(Python+Qt)学习随笔:树型部件QTreeWidget的itemAbove、itemBelow方法做用探究》。

上项和下项的访问方法以下:
  • itemAbove方法
    调用方法:QTreeWidgetItem itemAbove(QTreeWidgetItem item)
    返回参数item项之上的项。
  • itemBelow方法
    调用方法:QTreeWidgetItem itemBelow(const QTreeWidgetItem item)
    返回参数item项之下的项。
注意:当项折叠和展开时,上项和下项会跟随界面的变化而变化。

4.4.二、获取指定位置项的itemAt方法

QTreeWidget的itemAt方法经过视口内的坐标点获取对应坐标位置的项,相关调用方法以下:

  • QTreeWidgetItem itemAt( QPoint p)
  • QTreeWidgetItem itemAt(int x, int y)

经过该方法能够获取到视口上对应坐标所在的项,若是对应坐标位置无项则返回None。

4.4.三、获取可见项视口位置的矩形

树型部件的visualItemRect方法能够返回参数指定项在视口矩形

QRect visualItemRect( QTreeWidgetItem item)
当项在树型部件中不可见时,返回值为一个空矩形(一个没有矩形坐标、长宽属性的QRect()对象)。

4.五、QTreeWidget的标题属性

树型部件窗口能够有一个标题头,其中包含部件中每一个列的节(即标题)。QTreeWidget的标题属性包括两部分,一部分是标题项,一部分标题头相关属性。

4.5.一、标题项访问方法

标题头其实是一个QTreeWidgetItem项,所以标题项相关的属性就是QTreeWidgetItem想的属性,相关属性的访问就经过QTreeWidgetItem的方法去访问。树型部件提供了这个项的访问方法headerItem和setHeaderItem。调用语法以下:

  • QTreeWidgetItem QTreeWidget.headerItem()
  • QTreeWidget.setHeaderItem(QTreeWidgetItem item)

若是须要改变标题,能够经过项的setText方法进行。如:

self.treeWidget.headerItem().setText(0, "文件或目录名")
        self.treeWidget.headerItem().setText(1, "类型")
        self.treeWidget.headerItem().setText(2, "大小")

4.5.二、改变标题文本的方法

除了用上面的方法根据标题项设置标题文本外,还可使用setHeaderLabel改变标题首列的标题文本,也可使用setHeaderLabels改变从首列开始的多个列的标题文本,具体列数看参数传递列表的元素个数。调用语法以下:

  • setHeaderLabel(str label)
  • setHeaderLabels(labels:Iterable[str])

示例代码:

self.treeWidget.setHeaderLabels(("文件或目录名",'类型'))

4.5.三、标题头相关属性访问方法

QTreeWidget标题相关属性能够在Designer中设置,如图:
在这里插入图片描述
这些属性是从QTreeView继承的。关于这些属性的使用,请参考《PyQt(Python+Qt)学习随笔:QTreeView的标题表头header相关属性》。

5、QTreeWidget小结

QTreeWidget树型部件是一种内置存储model的便利类,它能够方便的呈现树型数据。QTreeWidget构造后,自动建立隐形根节点,隐形根节点不可见但可访问,隐形根节点下的子项就是树型部件的顶层项,顶层项建立后能够加入到树型部件中,顶层项能够继续添加子项,子项还能够再添加子项。相关项能够选中、删除和访问,部分操做能触发特定的信号,经过这些信号能够确认操做影响的数据。

广告

老猿关于PyQt的付费专栏《使用PyQt开发图形界面Python应用》只须要9.9元,该部分与第十五章的内容基本对应,但一样内容在付费专栏上整体来讲更详细、案例更多。本节内容对应付费专栏的《第二十二章、 Model/View便利类树型部件QTreeWidget》。若是有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

老猿Python,跟老猿学Python!