zoukankan      html  css  js  c++  java
  • 第15.27节 PyQt(Python+Qt)入门学习:Model/View架构中的便利类QTreeWidget详解

    一、引言

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

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

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

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

    二、树型部件中的QTreeWidgetItem项

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

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

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

    2.1、QTreeWidgetItem的构造方法

    QTreeWidgetItem的构造方法如下:

    • 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 )

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

    • 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.2、QTreeWidgetItem的其他重要属性或方法

    2.2.1、项操作方法

    2.2.1.1、项标记flags相关方法

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

    2.2.1.2、判断项是否disable方法

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

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

    2.2.1.3、判断项是否首列跨所有列展示

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

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

    2.2.1.4、项隐藏相关方法

    项可以隐藏不显示,通过方法isHidden()判断项是否隐藏,通过setHidden(bool hide)方法设置项是否隐藏。

    2.2.1.5、项选中相关方法

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

    2.2.2、子项、父项相关操作方法

    2.2.2.1、追加子项方法

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

    如果要插入的项原来已经在QTreeWidgetItem对象中,则该项不会重复加入,如果是多项中有部分项已经在QTreeWidgetItem对象中,则这部分项不会重复加入,其他项则可以加入。

    2.2.2.2、插入子项方法

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

    2.2.2.3、项下子项的指示符展示原则childIndicatorPolicy

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

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

    childIndicatorPolicy属性默认值为DontShowIndicatorWhenChildless,可以通过childIndicatorPolicy()和setChildIndicatorPolicy(QTreeWidgetItem.ChildIndicatorPolicy policy)来访问。

    2.2.2.4、展开子项

    如果一个项有子项,可以调用setExpanded(bool expand)方法来展开或折叠其子项,项的子项是否折叠可以通过isExpanded()方法来判断。

    2.2.2.5、获取项的父项或子项

    可以通过child(int index) 方法获取项的子项列表中序号为index的项,注意index取值从0开始。子项的个数可以通过childCount()方法获取,index的值必须小于子项的个数,否则返回None。

    项的父项可以通过parent() 方法返回,但项如果是顶级项,parent()方法返回None,而不是返回对应的QTreeWidget对象,如果要返回项对应的QTreeWidget对象,可用treeWidget()方法,这个方法对顶级项和非顶级项都是一样的。

    2.2.2.6、获取子项索引

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

    2.2.2.6、removeChild删除子项

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

    2.2.2.7、takeChild删除并返回子项

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

    QTreeWidgetItem takeChild(int index)
    

    如果执行失败,返回None。

    2.2.2.8、takeChildren删除所有子项

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

    2.2.2.9、sortChildren对子项排序

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

    sortChildren(int column, Qt.SortOrder order)
    

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

    2.2.2.10、获取项对应的树型部件对象

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

    2.2.3、项中列相关的操作方法

    2.2.3.1、项列数columnCount()方法

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

    2.2.3.2、项中列数据的访问方法

    树型部件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.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.4、项中列的复选状态访问方法

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

    注意:

    2.2.3.5、项中列的其他操作方法

    项中的列还可以:

    • 通过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

    三、QTreeWidget的属性

    3.1、概述

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

    3.2、columnCount属性

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

    3.3、topLevelItemCount属性

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

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

    四、QTreeWidget的主要方法

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

    4.1、构造方法

    QTreeWidget的构造方法非常简单:

    QTreeWidget(QWidget parent = None)

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

    4.2、项操作访问方法

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

    4.2.1、当前项操作访问方法

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

    4.2.2、当前列访问方法

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

    4.2.3、获取选中项的方法

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

    4.2.4、搜索项

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

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

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

    4.2.5、项排序

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

    sortItems(int column, Qt.SortOrder order)
    

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

    4.2.6、项编辑

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

    4.2.6.1、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.2、editItem触发编辑

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

    editItem(QTreeWidgetItem item, int column = 0)
    

    4.2.6.3、openPersistentEditor打开持久编辑器

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

    openPersistentEditor(QTreeWidgetItem item, int column = 0)

    该方法没有返回值。

    4.2.7、项首列跨所有列展示

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

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

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

    这两个方法与项方法isFirstColumnSpanned、setFirstColumnSpanned的作用完全相同,就是方法名和参数有所区别,由于是部件方法,参数中必须指定项,而isFirstColumnSpanned、setFirstColumnSpanned本身是项的实例方法,无需指定项。

    4.3、顶层项操作访问方法

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

    4.3.1、取指定位置顶层项topLevelItem方法

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

    4.3.2、访问QTreeWidget的隐形根节点

    该方法严格来说不属于顶层项的方法,只是只有一个方法且确实能通过它方法顶层项,因此在此还是归并到顶层项的方法中。

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

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

    QTreeWidgetItem invisibleRootItem()

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

    4.3.3、给QTreeWidget增加顶层项的方法

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

    4.3.3.1、追加顶层项的方法

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

    如果要插入的项原来已经在QTreeWidget的项中,则该项不会重复加入,如果是多项中有部分项已经在QTreeWidget的项中,则这部分项不会重复加入,其他项则可以加入。

    4.3.3.2、插入顶层项方法

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

    4.3.4、获取顶层项位置的indexOfTopLevelItem方法

    通过调用树型部件的indexOfTopLevelItem方法可以获得对应项在顶层项的位置,调用语法如下:

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

    4.3.5、删除指定位置的顶层项takeTopLevelItem方法

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

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

    4.4、与项位置相关的方法

    4.4.1、项的上项和下项

    项在树型部件中展示时,其界面上面的项称为上项,其界面下面的项称为下项,上项和下项与项不一定是同一层级的。如下图:
    在这里插入图片描述
    上图中蓝色选中的项(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.2、获取指定位置项的itemAt方法

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

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

    通过该方法可以获取到视口上对应坐标所在的项,如果对应坐标位置无项则返回None。

    4.4.3、获取可见项视口位置的矩形

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

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

    4.5、QTreeWidget的标题属性

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

    4.5.1、标题项访问方法

    标题头实际上是一个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.2、改变标题文本的方法

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

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

    示例代码:

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

    4.5.3、标题头相关属性访问方法

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

    五、QTreeWidget小结

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

    广告

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

    老猿Python,跟老猿学Python!

  • 相关阅读:
    C# List<T>中Select List Distinct()去重复
    Spring.Net 简单入门学习
    [ASP.NET MVC]:
    打车题
    Vue------发布订阅模式实现
    Vue----数据响应原理
    小程序自定义导航栏_navigationStyle
    CleanWebpackPlugin最新版本使用问题
    js-事件函数调用简化
    用XHR简单封装一个axios
  • 原文地址:https://www.cnblogs.com/LaoYuanPython/p/12570431.html
Copyright © 2011-2022 走看看