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

1、引言

表格部件为应用程序提供标准的表格显示工具,在表格内能够管理基于行和列的数据项,表格中的最大数据项数为总行数和总列数的乘积,另外在表格中能够设置水平和垂直标题。html

表格部件对应类为QTableWidget ,QTableWidget 表格部件中的项类型为QTableWidgetItem类。QTableWidget 从QTableView派生的子类,内置默认模型,若是表格展示的应用须要使用本身的数据模型,则应使用QTableView类,而不是QTableWidget 类。python

2、QTableWidget的属性

2.一、概述

除了从父类继承的属性外,在Designer中QTableWidget只有两个属性,就是行数rowCount和列数columnCount,另外还有一部分就是用于设置表头的属性。如图:
在这里插入图片描述web

2.二、行数rowCount

QTableWidget的rowCount属性保存表格部件中的行数,在QTableWidget建立时若是没有指定行数,则缺省行数为0,QTableWidget建立后能够经过 setRowCount方法调整行数。编辑器

要获取当前表格部件中的行数,能够经过rowCount()方法获取,要设置表格部件的行数,能够经过setRowCount(int rows)调整表格的行数,若是参数rows小于如今表格中的实际行数,则表格中超出参数的行数数据会丢弃,就算是后面将行数或列数恢复也不能恢复相关数据。ide

2.三、列数columnCount

columnCount属性保存表格部件中的列数,相关属性和操做方法和rowCount相似。在QTableWidget建立时若是没有指定列数,则缺省列数为0,QTableWidget建立后能够经过 setColumnCount方法调整。svg

columnCount能够经过columnCount()方法获取,经过setColumnCount(int columns)设置。工具

2.四、表头及属性

QTableWidget的表头包括横表头和竖表头,以下:
在这里插入图片描述
上面的“列1”、“列2”、“列3”为横表头,“行1”、“行2”、“行3”为竖表头。横表头可经过方法setHorizontalHeaderLabels来设置,竖表头能够经过setVerticalHeaderLabels来设置。这是建立表头的最简单方法,它们将为表的列和行提供简单的文本标题。学习

下面代码为上图设置表头的示例代码:测试

self.tableWidget.setVerticalHeaderLabels(['行1','行2','行3'])
        self.tableWidget.setHorizontalHeaderLabels(['列1','列2','列3'])

除了上述简单方法外,还能够从表格部件的项建立更复杂的表头,相关方法在下面介绍QTableWidget的方法时再介绍。大数据

除了设置表头文字外,表头还有相关属性设置,QTableWidget的表头属性是直接继承自QTableView的表头属性,相关属性的介绍请参考《PyQt(Python+Qt)学习随笔:QTableView的标题表头相关属性》。

3、QTableWidget的项QTableWidgetItem

3.一、概述

QTableWidgetItem类为QTableWidget类的项实例类,用于保存表格部件的信息。项的内容可包含文本、图标或复选框等。

默认状况下,QTableWidgetItem项是可用、可编辑、可选择和可选中的,而且能够用做拖放操做的源和拖放目标。若是要改变相关设置,能够经过使用setFlags()来更改每一个项的标志(关于项的标记请参考《PyQt(Python+Qt)学习随笔:Model中项的标记flags取值及枚举类型Qt.ItemFlag》)。

QTableWidgetItem的方法分为构造方法、位置相关方法、数据及展示内容相关、操做相关四类。

3.二、构造方法

QTableWidgetItem的构造方法有4个:

  1. QTableWidgetItem(int type = Type):构建一个空项
  2. QTableWidgetItem( str text,int type = Type):构建一个带文本的项
  3. QTableWidgetItem( QIcon icon, str text, int type = Type) :构建一个带图标和文本的项
  4. QTableWidgetItem( QTableWidgetItem other):从other复制项的内容构建一个新项

3.三、位置相关方法

QTableWidgetItem项在QTableWidget中的位置包括三个属性来决定,就是表格部件对象、行和列,因为这三个属性决定了项在界面的哪一个组件的哪一个地方,所以老猿将相关方法归类为位置相关方法。QTableWidgetItem项方法中:

  • QTableWidget tableWidget():返回项所在的表格部件实例,若是项没有插入到树型部件中,则返回None
  • int row() :返回项所在表格的行,注意是从0开始计数
  • int column():返回项所在表格的列,注意是从0开始计数

3.四、数据和展示相关方法

在部件中的数据有多种属性,包括文本数据、图标、复选状态、工具栏提示toolTip、whatsThis帮助、状态提示statusTip等,在Qt中将这些称为同一个项的不一样角色数据(关于数据的角色请参考《PyQt学习随笔:Model/View中诸如DisplayRole的数据角色及含义》)。这些数据为呈现数据的不一样状态状况,所以老猿将与此相关的方法归类为数据和展示相关方法。不一样角色的数据在Qt中能够经过data和setData方法带角色参数统一访问,也能够经过各自不一样的方法不带角色去访问。

3.4.一、项数据的data和setData访问方法

部件中的项数据能够经过项的data( int role) 方法获取项中指定列指定角色的数据,也能够经过setData(int role, QVariant value)方法设置指定角色的数据为value。例如项的文本能够经过data方法和setData方法使用Qt.DisplayRole、Qt.EditRole这两种角色去访问。

关于数据的角色请参考《PyQt学习随笔:Model/View中诸如DisplayRole的数据角色及含义》。

注意:
  • role虽然是整数,但其实是枚举类型 Qt.ItemDataRole
  • QVariant 表示任何PyQt的数据类型,因此value的类型没有约束
示例代码:
item.setData(QtCore.Qt.DecorationRole,QtGui.QIcon('.\\icon\\'+str(row+1)+'.gif'))#设置图标
        item.setData(QtCore.Qt.CheckStateRole, row%3) #设置复选状态
        item.setData(QtCore.Qt.TextAlignmentRole,col % 3)  #设置文本对齐方式
3.4.二、项文本数据访问的text和setText方法

项的文本能够经过data方法和setData方法使用Qt.DisplayRole、Qt.EditRole这两种角色去访问,除了这个方法外,还能够经过text() 和setText( str value)方法去访问。

  • text():获取项的文本数据
  • setText( str value):设置项的文本数据为value,注意没有返回值
3.4.三、项文本对齐方式访问的textAlignment和setTextAlignment方法

项中的文本能够设置水平和垂直对齐方式,相关对齐方式的访问方法调用方式以下:

  • int textAlignment() :返回对齐方式,返回类型是枚举类型Qt.Alignment,其实是整数
  • setTextAlignment(int alignment):设置对齐方式,无返回值
注:

对齐方式是一个Qt.Alignment枚举类型的组合,具体取值及含义请参考《PyQt(Python+Qt)学习随笔:QListView的itemAlignment属性》。

3.4.四、项中图标访问的icon和setIcon方法

能够经过icon()来访问项的图标,经过setIcon( QIcon icon)来设置项的图标。

以下面代码将顶的图标设置为指定文件:

item.setIcon(QtGui.QIcon(r'F:\小图标\动物\动物-025.gif'))
3.4.五、项复选状态访问方法

项能够单独设置复选状态,如图全部项都设置了复选状态,每行的复选状态不一样:
在这里插入图片描述
项的复选状态能够经过checkState()来获取,若是要改变项的复选状态能够调用setCheckState(Qt.CheckState state)来实施。

注意:

3.4.六、项提示信息相关操做方法

提示信息包括工具栏提示、状态栏提示和whatsThis提示:

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

关于这三个提示信息的区别请参考《PyQt(Python+Qt)学习随笔:Qt Designer中部件的toolTip、toolTipDuration、statusTip、whatsThis属性》。

3.4.七、sizeHint相关方法

关于QTableWidgetItem项的sizeHint属性,Qt中的文档说明很是简单,做用也没有展开说明,仅介绍QTableWidgetItem中sizeHint为项的缺省大小,若是没有设置则根据项的数据自动计算项的大小。

为此老猿作了大量测试和验证,最终确认了QTableWidgetItem项的sizeHint的做用,QTableWidgetItem的sizeHint在项对应QHeadView表头的sectionResizeMode值为ResizeToContents时,做为计算项大小的一个因素:

  1. 判断项是否设置了sizeHint,若是没有设置则按项的内容计算项大小,确保项的内容在对应表头方向完整显示;
  2. 若是项设置了sizeHint,则取sizeHint的值做为项的大小。

具体请参考《PyQt学习随笔:QTableWidget项sizeHint的做用以及与QHeadView的sectionResizeMode、ResizeToContents的关系》和《PyQt(Python+Qt)学习随笔:QTableWidget表格部件中行高和列宽的计算方式》。

项的sizeHint相关访问方法及调用语法以下:
  • QSize sizeHint()
  • setSizeHint( QSize size)

3.五、项操做相关方法

QTableWidget中项操做相关的属性包括是否可用、是否可选中、是否可编辑、是否可复选、是否选中、是否复选等,这些属性的设置与影响界面上项的操做,因此老猿将其归类项操做相关方法。这些项操做相关方法全部Model/View相关类涉及项操做都是同样的。因为复选状态同时是项的展示状态,在前面数据和展示相关方法中已经介绍相关方法。

3.5.一、项标记相关方法

项的标记用于标记项是否可操做,由多个属性位组合而成,具体项标记的取值及含义请参考《PyQt(Python+Qt)学习随笔:Model中项的标记flags取值及枚举类型Qt.ItemFlag》。

项标记的访问方法及调用语法以下:

  • Qt.ItemFlags flags()
  • setFlags(Qt.ItemFlags flags)

3.5.二、项是否选中相关方法

项是否被用户选中能够经过isSelected方法获取,若是要经过代码设置项的选中状态,则调用setSelected方法,相关调用语法以下:

  • bool isSelected()
  • setSelected(bool select)

4、QTableWidget的主要方法

除了从父类继承的方法外,QTableWidget的方法老猿将其概括为构造方法、部件状态访问方法、项操做方法、项查找和定位方法、表头操做方法五大类。

4.一、构造方法

QTableWidget有2个构造方法:

  • QTableWidget(QWidget parent = None) :建立一个0行0列的QTableWidget实例
  • QTableWidget(int rows, int columns, QWidget parent = None):建立一个rows行columns列的QTableWidget实例

这两个构造方法的区别就是后者指定了部件的行数和列数,而前者行数和列数为0,须要在实例构建后再另外去指定行数和列数。参数parent 通常传部件所在窗口,不传也不要紧。

注:

这里的构造方法是沿用C++的说法,Python中的构造方法是__init__。

4.二、部件状态访问方法

老猿将部件中反映部件当前状况的一些方法归类为部件状态访问方法,包括部件的行数、列数、当前项、当前行、当前列等属性访问方法。因为部件行数和列数的访问方法在部件属性中已经介绍了,在此不重复介绍。

4.2.一、当前项访问方法

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

  • QTableWidgetItem currentItem() :返回当前项对应项对象,若是没有当前项则返回None
  • setCurrentItem(QTableWidgetItem item):设置当前项
  • setCurrentItem(QTableWidgetItem item, QItemSelectionModel.SelectionFlags command):设置当前项
  • setCurrentCell(int row, int column):设置当前项
  • setCurrentCell(int row, int column, QItemSelectionModel.SelectionFlags command):设置当前项
注意:
  1. 后面4个方法都是设置当前项,方法名为setCurrentItem的参数是QTableWidgetItem实例,方法名为setCurrentCell的参数是行和列,即这两类方法依据的项定位方法不一样
  2. 参数中带command参数的,要求除了将当前项改成参数确认的项以外,还要求有额外的响应,具体响应由command参数确认。关于QItemSelectionModel.SelectionFlags 请参考《PyQt(Python+Qt)学习随笔:Mode/View中的枚举类QItemSelectionModel.SelectionFlag取值及含义》;
  3. 若是当前项没有,则currentItem()方法返回None。

4.2.二、当前行和列访问方法

当前项所在的行和列,既能够经过当前项的QTableWidgetItem实例对象的行号(row()方法)和列号(column()方法)获取,也能够直接经过QTableWidget获取。调用语法以下:

  • int currentColumn()
  • int currentRow()
    若是部件没有当前项,则上述两个方法返回-1。

4.三、部件中的项操做方法

部件中的项操做包括设置项、删除项、编辑项等。

4.3.一、设置项setItem方法

setItem用于在表格部件QTableWidget建立后,设定指定行和指定列的项为一个QTableWidgetItem实例对象。调用语法以下:
setItem(int row, int column, QTableWidgetItem item)

注意:
  • 该方法没有返回值,但会触发itemChanged信号
  • 在使用setItem以前,须要确保表格部件的行数和列数已经设置,且参数 row和column在行数和列数的范围内,不然设置不会成功,这也意味着表格部件的行数和列数不能随着项的增长自动增长,必须预约义好
示例代码:
for row in range(5):
            for col in range(3):
                item = QtWidgets.QTableWidgetItem(f"({row},{col})" )

                self.tableWidget.setItem(row,col,item)

4.3.二、触发编辑项的editItem方法

QTableWidget提供了触发项编辑的方法,调用语法以下:
editItem(QTableWidgetItem item)

注意:
  • editItem方法生效必须设置项的标记flags为可编辑
  • editItem一次只能触发一个项进行编辑,一旦退出编辑状态(如改变焦点),除非再次调用editItem或设置editTriggers触发编辑或打开永久编辑器不然对应项不能再编辑
  • 连续屡次调用editItem,中间没有触发事件处理,则只有第一次调用生效,后续调用无效

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

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

openPersistentEditor(QTableWidgetItem item)

该方法没有返回值。

4.3.四、从表格中取并移除项的takeItem方法

takeItem方法是从表格部件中取一个项返回并从部件中删除该项,调用语法以下:
QTableWidgetItem takeItem(int row, int column)

4.3.五、项排序

项排序是指针对表格部件中的数据行进行排序,调用语法以下:
sortItems(int column, Qt.SortOrder order = Qt.AscendingOrder)
排序依据参数column指定列进行。Qt.SortOrder为枚举类,有两个常量值,分别为:AscendingOrder升序,对应数值为0,DescendingOrder为降序,对应数值为1。

4.四、部件中项的查找和定位方法

项的查找和定位方法主要是查找特定的项和项的位置属性。

4.4.一、搜索项

在表格部件中,能够根据文本以及匹配模式来搜索知足条件的项,调用语法:
list[QTableWidgetItem] findItems( str text, Qt.MatchFlags flags)

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

4.4.二、访问选中项

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

调用语法:

list[QTableWidgetItem] selectedItems()

4.4.三、获取指定行和列的项

根据行和列能够获取对应位置的项,调用语法以下:
QTableWidgetItem item(int row, int column)

若是对应位置没有项,则返回None。

4.4.四、获取指定位置的项

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

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

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

4.4.五、获取指定项的行和列

QTableWidget中能够根据项实例去定位项的行和列位置,调用方法以下:

  • int column( QTableWidgetItem item)
  • int row( QTableWidgetItem item)

若是对应项在QTableWidget表格部件中不存在,则返回-1。

4.4.五、获取指定逻辑行或列对应的界面可见行号和列号

4.4.5.一、相关概念

关于逻辑行、列和可见行、列的概念,在QTableWidget中没有介绍,老猿查了比较多的资料,并通过验证,最终才搞清楚相关概念。这里有几个关键点要说明一下:

  1. 逻辑行和逻辑列是指项自己在部件中存储数据的行和列,也是经过QTableWidgetItem项方法row()和column()返回的值
  2. 界面可见行和列是指在部件上的行号和列号,从部件中第一行和第一列数据开始到指定逻辑行或逻辑列在部件内的序号,但隐藏行和列(这里的隐藏包括经过表头方法hideSection实现、数据在视口外、在能够手工调整行和列大小时将其大小调整到最小不可见)也必须参与在内。这个地方是个坑,说是可见行和可见列,但实际上隐藏未展示的和在视口外的数据都是参与行号和列号的计数
  3. 仅当部件中的行或列经过表头的moveSection交换了行或列数据所在的位置时才出现逻辑行列和可见行列不一致的状况
4.4.5.二、可见行和列相关方法

要获取表格部件中的可见行号和列号,调用方法:

  • int visualColumn(int logicalColumn)
  • int visualRow(int logicalRow)
4.4.5.三、小结
  1. 表格部件QTableWidget的项设置方法(setItem)所使用的行和列是项的逻辑行号和列号,表示数据在表格部件的存储位置,表格部件中绝大多数方法所使用的行和列都是逻辑行和列。
  2. 仅当表格部件的表头使用moveSection方法才会致使表格部件的逻辑行列号可能和可见行列号不一致,行和列的隐藏以及超出视口都不会致使逻辑行列号可能和可见行列号不一致;
  3. 因为隐藏数据也在可见行列中计数,所以这儿的可见行列实际上是不许确的,visualColumn和visualRow这两个方法在使用上须要注意。
4.4.六、获取项所在矩形位置的visualItemRect方法

QTableWidget的visualItemRect方法返回参数对应项占用视口位置的矩形数据,调用语法以下:
QRect visualItemRect( QTableWidgetItem item)

注意:
一、该方法在item对应项在视口中不可见(即须要滚动才可见)时一样会返回对应的矩形数据,只不过在视口左上角左边或上边的数据对应的横坐标或纵坐标为负数;
二、若是项对应行或列被经过表头方法hideSection隐藏了,则返回的矩形为一个空矩形(无坐标、长宽数据的矩形)。

案例:

在这里插入图片描述
上图中的QTableWidget部件中第一行数据已经经过hideSection进行了隐藏,第1列数据滚动到视口左边外去了,此时输出全部行第一列的可视矩形,输出结果以下:

(0,0): PyQt5.QtCore.QRect()
    (1,0): PyQt5.QtCore.QRect(-76, 0, 99, 19)
    (2,0): PyQt5.QtCore.QRect(-76, 20, 99, 19)
    (3,0): PyQt5.QtCore.QRect(-76, 40, 99, 19)
    (4,0): PyQt5.QtCore.QRect(-76, 60, 99, 19)
    (5,0): PyQt5.QtCore.QRect(-76, 80, 99, 19)
    (6,0): PyQt5.QtCore.QRect(-76, 100, 99, 19)
    (7,0): PyQt5.QtCore.QRect(-76, 120, 99, 19)

能够看到第一行第一列由于隐藏了是个空矩形,其余行的第一列x坐标都是负数。

4.4.七、返回选中项范围的矩形列表

在QTableWidget对项的操做支持选中多个项的状况下,能够经过方法selectedRanges返回选中矩形的列表,经过方法setRangeSelected将指定矩形范围的项选中或去选中。相关方法调用语法以下:

  • list[QTableWidgetSelectionRange] selectedRanges()
  • setRangeSelected( QTableWidgetSelectionRange range, bool select)
注:
  • QTableWidgetSelectionRange描述一个基于逻辑项位置连续的矩形范围,其矩形范围的左上角坐标为该范围内左上角逻辑项的逻辑行号和列号,右下角为右下角逻辑项的逻辑行号和列号。注意这里是指逻辑项而不是可见项
  • 因为选中的项可能不连续,所以selectedRanges返回的多是多个QTableWidgetSelectionRange矩形的列表,每一个矩形内是一个连续的选中范围

4.五、表头操做方法

QTableWidget表格部件的表头包括水平表头和竖直表头,水平表头每节对应表格的一列,竖直表头对应表格的一行。如图:
在这里插入图片描述
上图中的“行”+编号的项就是竖直表头的一个项(也称为1节),“列”+编号的项就是水平表头的一个项(节)。

4.5.一、设置水平表头的setHorizontalHeaderLabels方法

setHorizontalHeaderLabels用于一次性顺序设置水平表头多个节显示的文本,调用语法以下:

setHorizontalHeaderLabels( Iterable[str] labels)

4.5.二、设置竖直表头的setVerticalHeaderLabels

setVerticalHeaderLabels用于一次性顺序设置竖直表头多个节显示的文本,调用语法以下:
setVerticalHeaderLabels( Iterable[str] labels)

其余的方面与setHorizontalHeaderLabels方法相同。

4.5.三、访问水平节对应项

前面介绍了,表头的一个节实际上对应一个项,项的类型与表格部件的项类型相同,都是QTableWidgetItem实例对象。水平节对应项能够经过方法horizontalHeaderItem和setHorizontalHeaderItem方法访问,调用语法以下:

  • QTableWidgetItem horizontalHeaderItem(int column)
  • setHorizontalHeaderItem(int column, QTableWidgetItem item)

4.5.四、访问竖直节对应项

相似setHorizontalHeaderItem,QTableWidget提供了verticalHeaderItem、setVerticalHeaderItem方法,调用语法以下:

  • QTableWidgetItem verticalHeaderItem(int row)
  • setVerticalHeaderItem(int row, QTableWidgetItem item)

相关方法使用与访问水平节相似,在此不重复说明。

4.5.五、从表头节中取下节对应项

QTableWidget能够取下表头节对应项并返回,相关方法以下:

  • QTableWidgetItem takeHorizontalHeaderItem(int column)
  • QTableWidgetItem takeVerticalHeaderItem(int row)

对应节的项被取下后,表头对应节的标签将自动变动为节的序号。

4.5.六、表头属性相关访问方法

在Designer中,QTableWidget有以下表头属性能够设置:
在这里插入图片描述
相关属性是从QTableView继承过来的,相关访问方法请参考《PyQt(Python+Qt)学习随笔:QTableView的标题表头相关属性》。

5、本节小结

QTableWidget表格部件在建立之后,必须设置其包含的行数和列数才能插入项,项的插入经过setItem()进行。表格部件的QTableWidgetItem项是可用、可编辑、可选择和可选中的,而且能够用做拖放操做的源和拖放目标。项初始化后,能够进行选择、复选、编辑、排序等操做,除排序外相关操做会触发对应信号,能够经过信号来获取操做数据信息。

广告

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

老猿Python,跟老猿学Python!