27. 基于项的控件
一、基于项的控件
PySide6 有专门的显示数据的控件和存储数据的模型,可以显示和存储不同形式的数据。显示数据的控件分为两类,一类是基于 项(item)的控件,另一类是基于 模型(model)的控件,基于项的控件是基于模型的控件的简便类。基于项的控件把读取到的数据存储到项中,基于模型的控件把数据存储到模型中,或通过模型提供读取数据的接口,然后通过控件把数据模型中的数据或关联的数据显示出来。
我们可以在终端中使用 pip 安装 PySide6 模块。默认是从国外的主站上下载,因此,我们可能会遇到网络不好的情况导致下载失败。我们可以在 pip 指令后通过 -i 指定国内镜像源下载。
pip install pyside6 -i https://mirrors.aliyun.com/pypi/simple
国内常用的 pip 下载源列表:
- 阿里云 https://mirrors.aliyun.com/pypi/simple
- 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple
- 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple
基于项的控件有 列表控件 QListWidget、表格控件 QTableWidget 和 树结构控件 QTreeWidget,它们是从基于模型的控件继承而来的,基于模型的控件有 QListView、QTableView 和 QTreeView,这些控件之间的继承关系如下所示。

QAbstractItemView 类的常用方法:
# 实例方法
setModel(model:QAbstractItemModel) -> None # 设置数据模型
setSelectionModel(selectionModel:QItemSelectionModel) -> None # 设置选择模型
setAlternatingRowColors(enable:bool) -> None # 设置交替色
# 槽方法
clearSelection() -> None # 清空选择
二、列表控件及其项
列表控件 QListWidget 由一列多行构成,每行称为一个项(item),每个项是一个 QListWidgetItem 对象。可以继承 QListWidgetItem 创建用户自定义的项,也可以先创建 QWidget 实例,在其上添加一些控件,然后把 QWidget 放到 QListWidgetItem 的位置,形成复杂的列表控件。
列表控件 QListWidget 是从 QListView 类继承而来的,用 QListWidget 类创建列表控件的方法如下所示:
QListWidget(parent:QWidget=None)
其中 parent 是 QListWidget 列表控件所在的父窗口或控件。
用 QListWidgetItem 创建列表项的方法如下所示:
QListWidgetItem(listview:QListWidget=None, type:int=QListWidgetItem.Type)
QListWidgetItem(text:str, listview:QListWidget=None, type:int=QListWidgetItem.Type)
QListWidgetItem(icon:Union[QIcon, QPixmap], text:str, listview:QListWidget=None, type:int=QListWidgetItem.Type)
其中 type 可取 QListWidgetItem.Type(值为 0)或 QListWidgetItem.UserType(值为 1000),前者是默认值,后者是用户自定义类型的最小值。可以用 QListWidgetItem 类创建子类,定义新的类型。
列表控件 QListWidget 的常用方法如下:
# 实例方法
addItem(item:QListWidgetItem) -> None # 在列表控件中添加项
addItem(label:str) -> None # 用文本创建并添加项
addItems(labels:Sequence[str]) -> None # 用文本列表创建添加多个项
insertItem(row:int, item:QListWidgetItem) -> None # 在列表控件中插入项
insertItem(row:int, label:str) -> None # 用文本创建项并插入项
insertItems(row:int, labels:Sequence[str]) -> None # 用文本列表创建项并插入多个项
setCurrentItem(item:QListWidgetItem) -> None # 设置当前项
currentItem() -> QListWidgetItem # 返回当前项
setCurrentRow(row:int) -> None # 指定第row行为当前行
currentRow() -> int # 返回当前行
selectedItems() -> List[QListWidgetItem] # 返回选择项的列表
row(item:QListWidgetItem) -> int # 返回当前项的行号
item(row:int) -> QListWidgetItem # 返回指定行的项
itemAt(p:QPoint) -> QListWidgetItem # 返回指定位置的项
itemAt(x:int, y:int) -> QListWidgetItem # 返回指定位置的项
itemFromIndex(index:QModelIndex) -> QListWidgetItem # 返回指定索引的项
visualItemRect(item:QListWidgetItem) -> QRect # 返回指定项的矩形
setItemWidget(item:QListWidgetItem, widget:QWidget) -> None # 把某控件显示在指定项的位置处
itemWidget(item:QListWidgetItem) -> QWidget # 返回指定项位置处的控件
removeItemWidget(item:QListWidgetItem) -> None # 删除指定项位置处的控件
openPersistentEditor(item:QListWidgetItem) -> None # 打开指定项的编辑框,用于编辑文本
isPersistentEditorOpen(item:QListWidgetItem) -> bool # 返回指定项的编辑框是否打开
closePersistentEditor(item:QListWidgetItem) -> None # 关闭指定项的编辑框
count() -> int # 返回项的数量
takeItem(row:int) -> QListWidgetItem # 从列表控件中删除并返回项
findItems(text:str, flags:Qt.MatchFlags) -> List[QListWidgetItem] # 返回匹配项的列表
setSortingEnabled(enable:bool) -> None # 设置列表控件是否可以排序
isSortingEnabled() -> bool # 返回列表控件是否可以排序
sortItems(order:Qt.AscendingOrder) -> None # 按照排序方式进行项的排序
supportedDropActions() -> Qt.DropActions # 返回列表控件支持的拖动和粘贴操作
mimeData(items:Sequence[QListWidgetItem]) -> QMimeData # 获取多个项的mime数据QMimeData
mimeTypes() -> List[str] # 返回mime数据的类型列表
# 槽方法
clear() -> None # 清空列表控件
scrollToItem(item:QListWidgetItem, hint=QAbstractItemView.ScrollHint.EnsureVisible) -> None # 滚动到指定项,使其可见
列表控件 QListWidget 的常用信号如下:
currentItemChanged(current:QListWidgetItem, previous:QListWidgetItem) # 当前项发生改变时发射信号
currentRowChanged(currentRow:int) # 当前行发生改变时发射信号
currentTextChanged(currentText:str) # 当前项的文本发生改变时发射信号
itemActivated(item:QListWidgetItem) # 单击或双击项,使其变成活跃项时发射信号
itemChanged(item:QListWidgetItem) # 项的数据发生改变时发射信号
itemClicked(item:QListWidgetItem) # 单击项时发射信号
itemDoubleClicked(item:QListWidgetItem) # 双击项时发射信号
itemEntered(item:QListWidgetItem) # 光标进入某个项时发射信号
itemPressed(item:QListWidgetItem) # 当鼠标在某个项按下时发射信号
itemSelectionChanged() # 项的选择状态发生改变时发射信号
用 setSortingEnabled(bool) 方法 设置是否可以进行排序;用 sortItems(order:Qt.AscendingOrder) 方法 设置排序方法,其中参数 order 是 Qt.AscendingOrder 类型的枚举值,可以取值如下:
Qt.AscendingOrder.AscendingOrder # 升序
Qt.AscendingOrder.DescendingOrder # 降序
用 findItems(text:str,flags:Qt.MatchFlags) 方法可以 查找满足匹配规则的项 List[QListWidgetItem],其中参数 flags 是 Qt.MatchFlags 类型的枚举值,可以取值如下:
Qt.MatchFlags.MatchExactly
Qt.MatchFlags.MatchFixedString
Qt.MatchFlags.MatchContains
Qt.MatchFlags.MatchStartsWith
Qt.MatchFlags.MatchEndsWith
Qt.MatchFlags.MatchCaseSensitive
Qt.MatchFlags.MatchRegularExpression
Qt.MatchFlags.MatchWildcard
Qt.MatchFlags.MatchWrap
Qt.MatchFlags.MatchRecursive
用 supportedDropActions() 方法 获取支持的拖放动作 Qt.DropAction, Qt.DropAction 可以取值如下:
Qt.DropAction.CopyAction # 复制
Qt.DropAction.MoveAction # 移动
Qt.DropAction.LinkAction # 链接
Qt.DropAction.IgnoreAction # 什么都不做
Qt.DropAction.TargetMoveAction # 目标对象接管
列表项 QListWidgetItem 的常用方法如下:
setText(text:str) -> None # 设置文字
text() -> str # 获取文字
setTextAlignment(alignment:Qt.Alignment) -> None # 设置文字对齐方式
setIcon(icon:QIcon) -> None # 设置图标
icon() -> QIcon # 获取图标
setToolTip(toolTip:str) -> None # 设置提示文字
setStatusTip(statusTip:str) -> None # 设置状态提示文字,需激活mouseTracking属性
setWhatsThis(whatsThis:str) -> None # 设置按Shift+F1键的显示文字
setFont(font:QFont) -> None # 设置字体
setForeground(brush:QColor) -> None # 设置前景色
setBackground(brush:QColor) -> None # 设置背景色
setCheckState(state:Qt.CheckState) -> None # 设置勾选状态
checkState() -> Qt.CheckState # 获取勾选状态
setFlags(flags:Qt.ItemFlag) -> None # 设置标识
setHidden(hide:bool) -> None # 设置是否隐藏
isHidden() -> bool # 获取是否隐藏
setSelected(select:bool) -> None # 设置是否选中
isSelected() -> bool # 获取是否选中
clone() -> QListWidgetItem # 克隆一个项
listWidget() -> QListWidget # 获取列表视图
write(out:QDataStream) -> None # 将项写入数据流
read(in:QDataStream) -> None # 从数据流中读取项
setData(role:int, value:Any) -> None # 设置某角色的数据
data(role:int) -> Any # 获取某角色的数据
用 setForeground(color:QColor) 方法和 setBackground(color:QColor) 方法可以 设置前景色和背景色,其中参数 QColor 可以取 QBrush、Qt.BrushStyle、Qt.GlobalColor、QGradient、QImage 或 QPixmap。
用 setCheckState(state:Qt.CheckState) 方法 设置项是否处于勾选状态,其中参数 state 是 Qt.CheckState 类型的枚举值,可以取值如下:
Qt.CheckState.Unchecked # 未勾选
Qt.CheckState.PartiallyChecked # 部分勾选,如果有子项
Qt.CheckState.Checked # 勾选
用 setFlags(flag:Qt.ItemFlags) 方法 设置项的标识,其中参数 flag 是 Qt.ItemFlags 类型的枚举值,可以取的值如下所示:
Qt.ItemFlag.NoItemFlags # 没有标识符
Qt.ItemFlag.ItemIsSelectable # 项可选
Qt.ItemFlag.ItemIsEditable # 项可编辑
Qt.ItemFlag.ItemIsDragEnabled # 项可以拖拽
Qt.ItemFlag.ItemIsDropEnabled # 项可以拖放
Qt.ItemFlag.ItemIsUserCheckable # 项可以勾选
Qt.ItemFlag.ItemIsEnabled # 项被激活
Qt.ItemFlag.ItemIsAutoTristate # 如有子项,则有第三种状态
Qt.ItemFlag.ItemNeverHasChildren # 项没有子项
Qt.ItemFlag.ItemIsUserTristate # 可在三种状态之际爱你循环切换
新建一个 ui.py 文件,用来存放 UI 相关的代码。
from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QLabel, QListWidget
from PySide6.QtWidgets import QVBoxLayout
class MyUi:
def setupUi(self, window:QWidget):
window.resize(800, 600) # 1.设置窗口对象大小
layout = QVBoxLayout(window) # 2.创建一个垂直布局
self.listWidget = QListWidget() # 3.创建列表控件对象,并添加到布局中
layout.addWidget(self.listWidget)
self.listWidget.addItem("木之本樱") # 4.向列表控件中添加值
self.listWidget.addItems(["御坂美琴", "夏娜", "赤瞳", "黑瞳"])
self.listWidget.insertItem(3, "涂山苏苏") # 5.向指定索引处插入值
self.listWidget.insertItems(3, ["白钰袖", "风铃儿"])
item = self.listWidget.item(1) # 6.获取指定项
item.setToolTip("超电磁炮") # 7.设置指定项的提示信息
self.listWidget.setCurrentItem(item) # 8.设置当前项
self.listWidget.setSelectionMode(QListWidget.SelectionMode.ExtendedSelection) # 9.设置选择模式
self.listWidget.setSelectionBehavior(QListWidget.SelectionBehavior.SelectItems) # 10.设置选择项的方式
self.listWidget.setViewMode(QListWidget.ViewMode.IconMode) # 11.设置显示模式
self.listWidget.setWordWrap(True) # 12.设置是否自动换行
self.label = QLabel() # 13.创建标签,并添加到布局中
layout.addWidget(self.label)
修改 widget.py 文件的内容。
import sys
from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QListWidgetItem
from ui import MyUi
class MyWidget(QWidget):
def __init__(self):
super().__init__() # 1.调用父类Qwidget类的__init__()方法
self.__ui = MyUi()
self.__ui.setupUi(self) # 2.初始化页面
self.__ui.listWidget.currentItemChanged.connect(self.listWidget_current_item_changed) # 3.当前项改变了触发信号
self.__ui.listWidget.itemClicked.connect(self.listWidget_item_clicked) # 4.当前项被点击触发信号
self.__ui.listWidget.itemActivated.connect(self.listWidget_item_activated) # 5.当前项被激活触发信号
self.__ui.listWidget.itemEntered.connect(self.listWidget_item_entered) # 6.当前项进入时触发信号
self.__ui.listWidget.itemPressed.connect(self.listWidget_item_pressed) # 7.当前项按下时触发信号
def listWidget_current_item_changed(self, current:QListWidgetItem, previous:QListWidgetItem):
self.__ui.label.setText(f"当前项被改变了,从【{previous.text()}】变成了【{current.text()}】")
def listWidget_item_clicked(self, item:QListWidgetItem):
self.__ui.label.setText(f"【{item.text()}】项被单击了")
def listWidget_item_activated(self, item:QListWidgetItem):
self.__ui.label.setText(f"【{item.text()}】项被激活了")
def listWidget_item_entered(self, item:QListWidgetItem):
self.__ui.label.setText(f"鼠标移入【{item.text()}】项")
def listWidget_item_pressed(self, item:QListWidgetItem):
self.__ui.label.setText(f"【{item.text()}】项被按下了")
if __name__ == "__main__":
app = QApplication(sys.argv) # 1.创建一个QApplication类的实例
window = MyWidget() # 2.创建一个窗口
window.show() # 3.显示窗口
sys.exit(app.exec()) # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
三、表格控件及其项
表格控件 QTableWidget 是从 QTableView 类继承而来的,由多行多列构成,并且含有行表头和列表头,表格控件的每个单元格称为一个项(item),每个项是一个 QTableWidgetItem 对象,可以设置每个项的文本、图标、颜色、前景色和背景色等属性。
用 QTableWidget 类创建表格控件的方法如下所示:
QTableWidget(parent:QWidget=None)
QTableWidget(rows:int, columns:int, parent:QWidget=None)
其中 parent 是表格控件 QTableWidget 所在的父窗口或控件, rows 和 columns 分别 指定表格对象的行和列的数量。
用 QTableWidgetItem 创建表格项的方法如下所示:
QTableWidgetItem(type=QTableWidgetItem.Type)
QTableWidgetItem(text:str, type=QTableWidgetItem.Type)
QTableWidgetItem(icon:QIcon, text:str, type=QTableWidgetItem.Type)
其中 type 可取 QTableWidgetItem.Type(值为 0)或 QTableWidgetItem.UserType(值为 1000),前者是默认值,后者是用户自定义类型的最小值。可以用 QTableWidgetItem 类创建子类,定义新表格项。
QTableWidget 类常用方法如下:
# 实例方法
setRowCount(rows:int) -> None # 设置行数
rowCount() -> int # 获取行数
setColumnCount(columns:int) -> None # 设置列数
columnCount() -> int # 获取列数
setItem(row:int, column:int, item:QTableWidgetItem) -> None # 在指定行和列处设置表格项
takeItem(row:int, column:int) -> QTableWidgetItem # 移除并返回指定表格项
setCurrentCell(row:int, column:int) -> None # 设置当前单元格
setCurrentItem(item:QTableWidgetItem) -> None # 设置当前的表格项
currentItem() -> QTableWidgetItem # 返回当前的表格项
currentRow() -> int # 返回当前行号
currentColumn() -> int # 返回当前列号
row(item:QTableWidgetItem) -> int # 返回指定表格项的行号
column(item:QTableWidgetItem) -> int # 返回指定表格项的列号
setHorizontalHeaderItem(column:int, item:QTableWidgetItem) -> None # 设置水平表头
setHorizontalHeaderLabels(labels:Sequence[str]) -> None # 用字符串序列设置水平表头
horizontalHeaderItem(column:int) -> QTableWidgetItem # 获取水平表头的表格项
takeHorizontalHeaderItem(column:int) -> QTableWidgetItem # 移除并返回水平表头的表格项
setVerticalHeaderItem(row:int, item:QTableWidgetItem) -> None # 设置垂直表头
setVerticalHeaderLabels(labels:Sequence[str]) -> None # 用字符串序列设置垂直表头
verticalHeaderItem(row:int) -> QTableWidgetItem # 获取垂直表头的表格项
takeVerticalHeaderItem(row:int) -> QTableWidgetItem # 移除并返回垂直表头的表格项
editItem(item:QTableWidgetItem) -> None # 编辑表格项
findItems(text:str, flags:Qt.MatchFlg) -> List[QTableWidgetItem] # 获取满足条件的表格项列表
item(row:int, column:int) -> QTableWidgetItem # 获取指定行和列处的表格项
itemAt(p:QPoint) -> QTableWidgetItem # 获取指定位置处的表格项
itemAt(x:int, y:int) -> QTableWidgetItem # 获取指定位置处的表格项
openPersistentEditor(item:QTableWidgetItem) -> None # 打开指定项的编辑框,用于编辑文本
isPersistentEditorOpen(item:QTableWidgetItem) -> bool # 返回指定项的编辑框是否打开
closePersistentEditor(item:QTableWidgetItem) -> None # 关闭指定项的编辑框
selectedItems() -> List[QTableWidgetItem] # 返回选择项的列表
setCellWidget(row:int, column:int, widget:QWidget) -> None # 设置单元格的控件
cellWidget(row:int, column:int) -> QWidget # 获取单元格的控件
removeCellWidget(row:int, column:int) -> None # 移除单元格的控件
setSortingEnabled(enable:bool) -> None # 设置表格控件是否可以排序
isSortingEnabled() -> bool # 返回表格控件是否可以排序
sortItems(order:Qt.SortOrder=Qt.AscendingOrder) -> None # 按照排序方式进行项的排序
supportedDropActions() -> Qt.DropAction # 返回支持的拖动和粘贴操作
# 槽函数
insertRow(row:int) -> None # 在指定位置插入行
removeRow(row:int) -> None # 移除指定行
insertColumn(column:int) -> None # 在指定位置插入列
removeColumn(column:int) -> None # 移除指定列
clear() -> None # 清空表格项和表头的内容
clearContents() -> None # 清空表格项的内容
scrollToItem(item:QTableWidgetItem, hint=QAbstractItemView.ScrollHint.EnsureVisible) -> None # 滚动到指定项,使其可见
QTableWidget 类常用信号如下:
cellActivated(row:int, column:int) # 单元格活跃时发射信号
cellChanged(row:int, column:int) # 单元格数据变化时发射信号
cellClicked(row:int, column:int) # 单击单元格时发射信号
cellDoubleClicked(row:int, column:int) # 双击单元格时发射信号
cellEntered(row:int, column:int) # 光标进入单元格时发射信号
cellPressed(row:int, column:int) # 光标在单元格按下按键时发射信号
currentCellChanged(currentRow:int, currentColumn:int, previousRow:int, previousColumn:int) # 当前单元格改变时发射信号
currentItemChanged(current:QTableWidgetItem, previous:QTableWidgetItem) # 当前表格项改变时发射信号
itemActivated(item:QTableWidgetItem) # 表格项活跃时发射信号
itemChanged(item:QTableWidgetItem) # 表格项数据变化时发射信号
itemClicked(item:QTableWidgetItem) # 单击表格时发射信号
itemDoubleClicked(item:QTableWidgetItem) # 双击表格时发射信号
itemEntered(item:QTableWidgetItem) # 光标进入表格时发射信号
itemPressed(item:QTableWidgetItem) # 光标在表格按下按键时发射信号
itemSelectionChanged() # 选择的表格项发射改变时发射信号
QTableWidgetItem 类常用方法如下:
setText(text:str) -> None # 设置文字
text() -> str # 获取文字
setTextAlignment(alignment:Qt.Alignment) -> None # 设置文字对齐方式
setIcon(icon:QIcon) -> None # 设置图标
icon() -> QIcon # 获取图标
setToolTip(toolTip:str) -> None # 设置提示文字
setStatusTip(statusTip:str) -> None # 设置状态提示文字,需激活mouseTracking属性
setWhatsThis(whatsThis:str) -> None # 设置按Shift+F1键的显示文字
setFont(font:QFont) -> None # 设置字体
setForeground(brush:QColor) -> None # 设置前景色
setBackground(brush:QColor) -> None # 设置背景色
setCheckState(state:Qt.CheckState) -> None # 设置勾选状态
checkState() -> Qt.CheckState # 获取勾选状态
setFlags(flags:Qt.ItemFlag) -> None # 设置标识
setSelected(select:bool) -> None # 设置是否选中
isSelected() -> bool # 获取是否选中
clone() -> QTableWidgetItem # 克隆一个项
tableWidget() -> QTableWidget # 获取表格视图
write(out:QDataStream) -> None # 将项写入数据流
read(in:QDataStream) -> None # 从数据流中读取项
setData(role:int, value:Any) -> None # 设置某角色的数据
data(role:int) -> Any # 获取某角色的数据
修改 ui.py 文件的内容。
from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QLabel, QTableWidget, QTableWidgetItem
from PySide6.QtWidgets import QVBoxLayout
class MyUi:
def setupUi(self, window:QWidget):
window.resize(800, 600) # 1.设置窗口对象大小
layout = QVBoxLayout(window) # 2.创建一个垂直布局
self.tableWidget = QTableWidget() # 3.创建一个表格控件,并添加到布局中
layout.addWidget(self.tableWidget)
self.tableWidget.setAlternatingRowColors(True) # 4.设置表格颜色交错显示
self.tableWidget.setRowCount(15) # 5.设置表格的行数
self.tableWidget.setColumnCount(10) # 6.设置表格的列数
self.tableWidget.setHorizontalHeaderLabels(["部门", "姓名", "性别", "年龄"]) # 7.设置表格的水平表头
self.tableWidget.setVerticalHeaderLabels(["1", "2", "3"]) # 8.设置表格的垂直表头
department_list = ["魔法部", "超能力部"]
person_list = [
{"department": department_list[0], "name": "木之本樱", "gender": "女", "age": 10},
{"department": department_list[0], "name": "夏娜", "gender": "女", "age": 15},
{"department": department_list[1], "name": "御坂美琴", "gender": "女", "age": 14},
]
for i in range(0, len(person_list)):
j = 0
for key, value in person_list[i].items():
item = QTableWidgetItem(str(value)) # 9.创建表格项
self.tableWidget.setItem(i, j, item) # 10.设置单元格的内容
j += 1
# 11.合并单元格
self.tableWidget.setSpan(0, 0, 2, 1)
self.label = QLabel() # 12.创建标签,并添加到布局中
layout.addWidget(self.label)
修改 widget.py 文件的内容。
import sys
from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QTableWidgetItem
from ui import MyUi
class MyWidget(QWidget):
def __init__(self):
super().__init__() # 1.调用父类Qwidget类的__init__()方法
self.__ui = MyUi()
self.__ui.setupUi(self) # 2.初始化页面
self.__ui.tableWidget.itemClicked.connect(self.tableWidget_item_clicked) # 3.单击表格项时激活信号
self.__ui.tableWidget.itemDoubleClicked.connect(self.tableWidget_item_double_clicked) # 4.双击表格项时激活信号
self.__ui.tableWidget.itemChanged.connect(self.tableWidget_item_changed) # 5.表格项数据改变时激活信号
self.__ui.tableWidget.itemSelectionChanged.connect(self.tableWidget_item_selection_changed) # 6.选择的表格项改变时激活信号
self.__ui.tableWidget.currentCellChanged.connect(self.tableWidget_current_cell_changed) # 7.当前表格项改变时激活信号
def tableWidget_item_clicked(self, item:QTableWidgetItem):
self.__ui.label.setText(f"【{item.text()}】表格项被单击了")
def tableWidget_item_double_clicked(self, item:QTableWidgetItem):
self.__ui.label.setText(f"【{item.text()}】表格项被双击了")
def tableWidget_item_changed(self, item:QTableWidgetItem):
self.__ui.label.setText(f"【{item.text()}】表格项内容被更改了")
def tableWidget_item_selection_changed(self):
self.__ui.label.setText("你选中的表格项更改了")
def tableWidget_current_cell_changed(self, current_row:int, current_column:int, previous_row:int, previsou_column:int):
previous_item = self.__ui.tableWidget.item(previous_row, previsou_column)
current_item = self.__ui.tableWidget.item(current_row, current_column)
if previous_item:
previous_item_text = previous_item.text()
else:
previous_item_text = None
current_item_text = current_item.text()
self.__ui.label.setText(f"你选中的单元格从【{previous_item_text}】变成了【{current_item_text}】")
if __name__ == "__main__":
app = QApplication(sys.argv) # 1.创建一个QApplication类的实例
window = MyWidget() # 2.创建一个窗口
window.show() # 3.显示窗口
sys.exit(app.exec()) # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
四、树控件及其项
树结构控件 QTreeWidget 继承自 QTreeView 类,它是 QTreeView 的便利类。树结构控件由 1 列或多列构成,没有行的概念。
树结构控件有 1 个或多个顶层项,顶层项下面有任意多个子项,子项下面还可以有子项,顶层项没有父项。顶层项和子项都是 QTreeWidgetItem,每个 QTreeWidgetItem 可以定义在每列显示的文字和图标,一般应在第 1 列中定义文字或图标,其它列中是否设置文字和图标,需要用户视情况而定。可以把每个项理解成树结构控件的一行,只不过行之间有层级关系,可以折叠和展开。
用 QTreeWidget 类创建树结构控件的方法如下。
QTreeWidget(parent:QWidget=None)
其中 parent 是 QTreeWidget 树结构控件所在的父窗口或控件。
用 QTreeWidgetItem 类创建树结构项的方法如下。
QTreeWidgetItem(type=QTreeWidgetItem.Type)
QTreeWidgetItem(strings:Sequence[str], type=QTreeWidgetItem.Type)
QTreeWidgetItem(treeview:QTreeWidget, type=QTreeWidgetItem.Type)
QTreeWidgetItem(treeview:QTreeWidget, strings:Sequence[str], type=QTreeWidgetItem.Type)
QTreeWidgetItem(parent:QTreeWidgetItem, type=QTreeWidgetItem.Type)
QTreeWidgetItem(parent:QTreeWidgetItem, strings:Sequence[str], type=QTreeWidgetItem.Type)
QTreeWidgetItem(parent:QTreeWidgetItem, after:QTreeWidgetItem, type=QTreeWidgetItem.Type)
其中 Sequence[str] 是 字符串序列,是各列上的文字。第 1 个参数是 QTreeWidget 时表示 项追加到树结构控件中,这时,新创建的项是顶层项。第 1 个参数是 QTreeWidgetItem 表示 父项,这时,新创建的项作为子项追加到父项下面;第 2 个参数是 QTreeWidgetItem 时表示 新创建的项插入到该项的后面。type 可以取 QTreeWidgetItem.Type(值是 0)或 QTreeWidgetItem.UserType(值是 1000,自定义类型的最小值)。
QTreeWidget 类常用方法如下:
# 实例方法
setColumnCount(columns:int) -> None # 设置列数
columnCount() -> int # 获取列数
currentColumn() -> int # 返回当前列
setColumnWidth(column:int, width:int) -> None # 设置列宽
setColumnHidden(column:int, hide:bool) -> None # 设置列是否隐藏
addTopLevelItem(item:QTreeWidgetItem) -> None # 添加顶层项
addTopLevelItems(items:Sequence[QTreeWidgetItem]) -> None # 添加多个顶层项
insertTopLevelItem(index:int, item:QTreeWidgetItem) -> None # 插入顶层项
insertTopLevelItems(index:int, items:Sequence[QTreeWidgetItem]) -> None # 插入多个顶层项
takeTopLevelItem(index:int) -> QTreeWidgetItem # 移除并获取顶层项
topLevelItem(index:int) -> QTreeWidgetItem # 返回索引是index的顶层项
topLevelItemCount() -> int # 返回顶层项的数量
indexOfTopLevelItem(item:QTreeWidgetItem) -> int # 返回顶层项的索引
setCurrentItem(item:QTreeWidgetItem) -> None # 把指定的项设置为当前项
setCurrentItem(item:QTreeWidgetItem, column:int) -> None # 设置当前项和当前列
currentItem() -> QTreeWidgetItem # 获取当前项
editItem(item:QTreeWidgetItem, column:int=0) -> None # 编辑表格项
openPersistentEditor(item:QTreeWidgetItem, column:int) -> None # 打开指定项的编辑框,用于编辑文本
isPersistentEditorOpen(item:QTreeWidgetItem, column:int) -> bool # 返回指定项的编辑框是否打开
closePersistentEditor(item:QTreeWidgetItem, column:int) -> None # 关闭指定项的编辑框
findItems(text:str, flags:Qt.MatchFlg, column:int=0) -> List[QTreeWidgetItem] # 获取满足条件项的列表
setHeaderItem(item:QTreeWidgetItem) -> None # 设置表头
setHeaderLabel(label:str) -> None # 设置表头的第一列文字
itemAt(p:QPoint) -> QTableWidgetItem # 获取指定位置处的表格项
itemAt(x:int, y:int) -> QTableWidgetItem # 获取指定位置处的表格项
invisibleRootItem() -> QTreeWidgetItem # 获取根项
itemAbove(item:QTreeWidgetItem) -> QTreeWidgetItem # 返回指定项之前的项
itemBelow(item:QTreeWidgetItem) -> QTreeWidgetItem # 返回指定项之后的项
selectedItems() -> List[QTreeWidgetItem] # 返回选择项的列表
setItemWidget(item:QTreeWidgetItem, column:int, widget:QWidget) -> None # 在指定项的指定列设置控件
itemWidget(item:QTreeWidgetItem, column:int) -> QWidget # 获取项上的控件
removeItemWidget(item:QTreeWidgetItem, column:int) -> None # 移除项上的控件
# 槽函数
scrollToItem(item:QTreeWidgetItem, hint=QAbstractItemView.ScrollHint.EnsureVisible) -> None # 滚动到指定项,使其可见
collapseItem(item:QTreeWidgetItem) -> None # 折叠项
collapseAll() -> None # 折叠所有项
expandItem(item:QTreeWidgetItem) -> None # 展开项
expandAll() -> None # 展开所有项
clear() -> None # 清空所有项
QTreeWidget 类常用信号如下:
currentItemChanged(current:QTreeWidgetItem, previous:QTreeWidgetItem) # 当前项改变时发射信号
itemActivated(item:QTreeWidgetItem, column:int) # 项活跃时发射信号
itemChanged(item:QTreeWidgetItem, column:int) # 项数据变化时发射信号
itemClicked(item:QTreeWidgetItem, column:int) # 单击项时发射信号
itemDoubleClicked(item:QTreeWidgetItem, column:int) # 双击项时发射信号
itemEntered(item:QTreeWidgetItem, column:int) # 光标进入项时发射信号
itemPressed(item:QTreeWidgetItem, column:int) # 在项上按下按键时发射信号
itemExpanded(item:QTreeWidgetItem) # 展开项时发射信号
itemCollapsed(item:QTreeWidgetItem) # 折叠项时发射信号
itemSelectionChanged() # 选择的项发射改变时发射信号
QTreeWidgetItem 类常用方法如下:
addChild(child:QTreeWidgetItem) -> None # 添加子项
addChildren(children:Sequence[QTreeWidgetItem]) -> None # 添加多个子项
insertChild(index:int, child:QTreeWidgetItem) -> None # 插入子项
insertChildren(index:int, children:Sequence[QTreeWidgetItem]) -> None # 插入多个子项
child(index:int) -> QTreeWidgetItem # 获取子项
childCount() -> int # 获取子项数量
takeChild(index:int) -> QTreeWidgetItem # 移除并返回子项
takeChildren() -> List[QTreeWidgetItem] # 移除并返回所有子项
removeChild(child:QTreeWidgetItem) -> None # 移除子项
parent() -> QTreeWidgetItem # 获取父项
treeWidget() -> QTreeWidget # 获取树视图
setText(column:int, text:str) -> None # 设置文字
text(column:int) -> str # 获取文字
setTextAlignment(column:int, alignment:Qt.Alignment) -> None # 设置文字对齐方式
setIcon(column:int, icon:QIcon) -> None # 设置图标
icon(column:int) -> QIcon # 获取图标
setToolTip(column:int, toolTip:str) -> None # 设置提示文字
setStatusTip(column:int, statusTip:str) -> None # 设置状态提示文字,需激活mouseTracking属性
setWhatsThis(column:int, whatsThis:str) -> None # 设置按Shift+F1键的显示文字
setFont(column:int, font:QFont) -> None # 设置字体
font(column:int) -> QFont # 获取字体
setForeground(column:int, brush:QColor) -> None # 设置前景色
setBackground(column:int, brush:QColor) -> None # 设置背景色
setCheckState(column:int, state:Qt.CheckState) -> None # 设置勾选状态
checkState(column:int) -> Qt.CheckState # 获取勾选状态
setFlags(flags:Qt.ItemFlag) -> None # 设置标识
setSelected(select:bool) -> None # 设置是否选中
isSelected() -> bool # 获取是否选中
setHidden(hide:bool) -> None # 设置是否隐藏
setDisabled(disabled:bool) -> None # 设置是否禁用
isDisabled() -> bool # 获取是否禁用
setExpanded(expand:bool) -> None # 设置是否展开
isExpanded() -> bool # 获取是否展开
setFirstColumnSpanned(span:bool) -> None # 设置是否只显示第一列的内容
setChildIndicatorPolicy(policy:QTreeWidgetItem.ChildIndicatorPolicy) -> None # 设置展开/折叠标识的显示策略
childIndicatorPolicy() -> QTreeWidgetItem.ChildIndicatorPolicy # 获取展开策略
columnCount() -> int # 获取列数
indexOfChild(child:QTreeWidgetItem) -> int # 获取子项的索引
sortChildren(column:int, order:Qt.SortOrder) -> None # 对子项进行排序
setData(column:int, role:int, value:Any) -> None # 设置某角色的数据
data(column:int, role:int) -> Any # 获取某角色的数据
修改 ui.py 文件的内容。
from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QLabel, QTreeWidget, QTreeWidgetItem
from PySide6.QtWidgets import QVBoxLayout
from PySide6.QtGui import QPixmap, Qt
class MyUi:
def setupUi(self, window:QWidget):
window.resize(800, 600) # 1.设置窗口对象大小
layout = QVBoxLayout(window) # 2.创建一个垂直布局
self.treeWidget = QTreeWidget() # 3.创建树控件,并添加到布局中
layout.addWidget(self.treeWidget)
self.treeWidget.setSortingEnabled(True) # 4.设置单击头部时是否可以排序
self.treeWidget.setAlternatingRowColors(True) # 5.设置每间隔一行颜色是否一致
self.treeWidget.setSelectionBehavior(QTreeWidget.SelectionBehavior.SelectItems) # 6.设置选中方式
self.treeWidget.setSelectionMode(QTreeWidget.SelectionMode.ExtendedSelection) # 7.设置选中模式
self.treeWidget.setColumnCount(10) # 8.设置树结构中的列数
self.treeWidget.setHeaderLabels(["部门", "姓名", "性别", "年龄"]) # 9.设置列标题名
department_list = ["魔法部", "超能力部"]
person_list = [
{"name": "木之本樱", "gender": "女", "age": 10, "department": department_list[0]},
{"name": "御坂美琴", "gender": "女", "age": 14, "department": department_list[1]},
{"name": "夏娜", "gender": "女", "age": 15, "department": department_list[0]},
]
for department in department_list:
# 一级节点
department_item = QTreeWidgetItem(self.treeWidget) # 10.创建一级节点
department_item.setText(0, department) # 11.设置一级节点的文本
self.treeWidget.addTopLevelItem(department_item) # 12.添加顶级节点
for person in person_list:
# 二级节点
if person["department"] == department:
person_item = QTreeWidgetItem(department_item) # 13.创建二级节点
person_item.setText(0, "") # 14.设置节点的文本
person_item.setIcon(0, QPixmap("1.ico")) # 15.设置节点的图标
person_item.setCheckState(0, Qt.CheckState.Unchecked) # 16.设置节点的选中状态
i = 1
for key, value in person.items():
if not key == "department":
person_item.setText(i, str(value))
if value == "木之本樱":
person_item.setCheckState(0, Qt.CheckState.Checked) # 17.设置选中状态
i += 1
self.treeWidget.expandAll() # 18.展开所有节点
self.label = QLabel() # 19.创建标签,并添加到布局中
layout.addWidget(self.label)
修改 widget.py 文件的内容。
import sys
from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QTreeWidgetItem
from ui import MyUi
class MyWidget(QWidget):
def __init__(self):
super().__init__() # 1.调用父类Qwidget类的__init__()方法
self.__ui = MyUi()
self.__ui.setupUi(self) # 2.初始化页面
self.__ui.treeWidget.itemClicked.connect(self.treeWidget_item_clicked) # 3.单击树节点时激活信号
self.__ui.treeWidget.itemDoubleClicked.connect(self.treeWidget_item_double_clicked) # 4.双击树节点时激活信号
self.__ui.treeWidget.itemExpanded.connect(self.treeWidget_item_expanded) # 5.展开树节点时激活信号
self.__ui.treeWidget.itemCollapsed.connect(self.treeWidget_item_collapsed) # 6.折叠树节点时激活信号
def treeWidget_item_double_clicked(self, item:QTreeWidgetItem, column:int):
self.__ui.label.setText(f"你双击了【{item.text(column)}】")
def treeWidget_item_clicked(self, item:QTreeWidgetItem, column:int):
self.__ui.label.setText(f"你单击了【{item.text(column)}】")
def treeWidget_item_expanded(self, item:QTreeWidgetItem):
self.__ui.label.setText(f"你展开了【{item.text(0)}】项")
def treeWidget_item_collapsed(self, item:QTreeWidgetItem):
self.__ui.label.setText(f"你收缩了【{item.text(0)}】项")
if __name__ == "__main__":
app = QApplication(sys.argv) # 1.创建一个QApplication类的实例
window = MyWidget() # 2.创建一个窗口
window.show() # 3.显示窗口
sys.exit(app.exec()) # 4.进入程序的主循环并通过exit()函数确保主循环安全结束

浙公网安备 33010602011771号