- item显示索引号
- 添加图标
- 绘制图形
- 设置文本样式
ListView 是一个基于模型-视图(Model-View)架构的控件,它通常用于显示大量的数据项。与 QListWidget 不同,QListView 不直接管理数据项的内容,而是通过一个数据模型(如 QStringListModel、QStandardItemModel 或自定义模型)来提供数据。若需要自定义 QListView 的每个item外观显示,需要自定义一个委托(QStyledItemDelegate 或 QItemDelegate)来绘制和编辑项。
QStyledItemDelegate类为模型中的数据项提供显示和编辑功能,通过重写paint()方法来绘制指定item的样式(背景、文字颜色、边框、图标)。
创建列表视图
#创建listview
import sys
from PyQt5 import QtCore, QtWidgets
class Ui_Dialog(object):
def __init__(self):
self.FormData=FormData()#listview控件数据处理
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 300)
self.listView = QtWidgets.QListView(Dialog)
self.listView.setGeometry(QtCore.QRect(20, 20, 361, 261))
self.listView.setObjectName("listView")
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
listview添加item
数据模型 QStringListModel与QStandardItemModel 区别
QStringListModel和QStandardItemModel都是Qt中用于处理字符串列表的模型类。QStringListModel是专门为QStringList设计的,而QStandardItemModel提供了更高级的功能,如每个条目可以有多个数据角色(例如,可以有一个显示在视图中的文本,另一个存储后台数据)。QStringListModel通常用于简单的字符串列表显示,而QStandardItemModel更灵活,适用于更复杂的需求
class FormData:
@staticmethod
def addStringModel(data:list, obj):#用于简单的字符串列表显示
model = QtCore.QStringListModel() # 创建数据模型
model.setStringList(data) # 模型添加数据
obj.setModel(model) #将模型设置到 QListView
#listview item绑定额外数据
@staticmethod
def addStandModel(data:str,info,obj):#添加视图中的文本数据和存储在后台的数据(不显示)
model = QStandardItemModel()# 创建一个 QStandardItemModel
obj.setModel(model)# 将模型关联到 QListView
item = QStandardItem()
# 添加额外信息
if isinstance(info,list):#多中额外信息
for i,value in enumerate(info):
item.setData(value, role=Qt.UserRole+i+1)
else:
item.setData(info, role=Qt.UserRole+1)#infor:可以为字典,字符串等数据存储在后台
#Qt.DisplayRole: 这是默认角色,用于显示文本或图标。Qt.DecorationRole: 用于设置图标。Qt.UserRole: 开始用于应用程序特定数据的自定义角色。
#添加默认文本内容
if bool(data):
item.setText(data,role=Qt.DisplayRole)
# 添加数据到模型
obj.model().appendRow(QStandardItem(item))#listview末尾添加
#listview添加多个item
self.FormData.addStringModel(['a','b','c'],self.listview)
#listview item 绑定额外数据
self.FormData.QStandardItemModel('a',['A','ascill值'],self.listview)
- item显示索引号
- 添加图标
- 绘制图形
- 设置文本样式
listview 每个item 绘制索引号和额外信息
重写QStyledItemDelegate类的pain方法,自定义item显示内容(索引号+额外文本,默认文本)
class PaintItem(QStyledItemDelegate):#
def paint(self, painter, option, index):
# 获取itme默认文本数据
# text = index.data(Qt.DisplayRole)
#******************绘制额外文本********************************
index_number = index.row() + 1# 获取当前项的索引号,int
info=index.data(Qt.UserRole+1)#额外文本
content=str(index_number)+' '+info+':'
# 设置索引号位置、尺寸
index_rect = option.rect.adjusted(0, 0, 0, 0) # left,top,width,height
# 绘制额外文本:索引号
painter.drawText(index_rect, Qt.AlignLeft | Qt.AlignVCenter, content)
# 获取索引号文本的尺寸
font_metrics = QFontMetrics(painter.font())
text_width = font_metrics.width(content)
# ******************绘制默认文本********************************
# 设置默认文本的位置,防止与索引号重叠
option.rect.setX(text_width+5)
# 绘制默认文本
super(PaintItem, self).paint(painter, option, index)
listview添加代理,自定义显示内容
#设置项代理为自定义的IndexDelegate
delegate = PaintItem()
self.listview.setItemDelegate(delegate)
listview 每个item 添加图标、背景、文本颜色、边框
#自定义代理类:自定义委托,重写paint()方法来绘制指定item的样式(背景、文字颜色、边框、图标)
class PaintItem(QStyledItemDelegate):
def __init__(self,spriteData=None,pixmap=None,addIcon=False):
super().__init__()
self.spriteData=spriteData#精灵图
self.pixmap=pixmap#
self.addIcon=addIcon#item是否添加图标
#绘制、显示item样式
def paint(self, painter, option, index):
# 保存painter的当前配置
painter.save()
#绘制图标
idd=index.data(Qt.UserRole+1)
imgData = self.spriteData[idd]
# 从精灵图中提取指定位置、大小的图片
sprite_pixmap = self.pixmap.copy(imgData['x'], imgData['y'], imgData['w'], imgData['h'])
sprite_pixmap=sprite_pixmap.scaled(16, 16, Qt.KeepAspectRatio) # 设置图片大小为21x21
icon = QtGui.QIcon(sprite_pixmap)
# icon=icon.pixmap(21, 21)
# 绘制图标
icon.paint(painter, option.rect, Qt.AlignLeft | Qt.AlignVCenter)
#**************设置item背景色、边框和文本颜色****************
# 获取item的数据
item_text = index.data(Qt.DisplayRole)#index.data(Qt.UserRole)
background_color = QtGui.QColor(36,36,36)
text_color = QtGui.QColor(255, 255, 255) # 白色文本
#绘制背景
painter.fillRect(option.rect, background_color)#painter.fillRect(option.rect, background_color)
# 设置文本颜色
painter.setPen(text_color)
#绘制文本
painter.drawText(option, Qt.AlignLeft, item_text)#option.rect 是一个 QRect 对象,它定义了要绘制的项的矩形区域。这个矩形通常对应于项在视图中的位置和大小。Qt.AlignCenter 是一个枚举值,用于指定文本的对齐方式。在这种情况下,它表示文本应该在 option.rect 指定的矩形中居中对齐。
# # 设置边框
# border_color, border_width = QtGui.QColor(61,61,61), 1# 设置边框颜色和宽度
# pen = QtGui.QPen(border_color, border_width)
# painter.setPen(pen)
# # #绘制边框
# painter.drawRect(option)
# 恢复painter的原始配置
painter.restore()
listview item 绘制按钮
class PaintItem(QStyledItemDelegate):
def paint(self, painter, option, index):
#绘制默认文本
super(CustomDelegate, self).paint(painter, option, index)
# 绘制按钮的区域
button_rect = QRect(option.rect.right() - 50, option.rect.top(), 50, option.rect.height())
painter.setBrush(QBrush(QColor(200, 200, 200)))
painter.drawRect(button_rect)
painter.drawText(button_rect, int(Qt.AlignCenter), "Button")
#设置项代理为自定义的IndexDelegate
delegate = PaintItem()
self.listview.setItemDelegate(delegate)