当前位置: 首页 > article >正文

PyQt5:自定义QListView显示

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

http://www.kler.cn/a/465918.html

相关文章:

  • 类的定义和使用(python)
  • Eplan 项目结构(高层代号、安装地点、位置代号)
  • Postgresql 命令还原数据库
  • AngularJS 指令:深入解析与高级应用
  • C/C++在鸿蒙系统中主要用于硬件开发和系统级编程
  • Android授权USB使用权限示例
  • 高质量C++小白教程:2.10-预处理器简介
  • GIT 企业级开发学习 1
  • Emacs折腾日记(七)——布尔变量、逻辑运算符与位运算
  • token、cookie和session
  • 【AIGC】 ChatGPT实战教程:如何高效撰写学术论文引言
  • MR30分布式IO模块助力PLC,打造高效智能仓储系统
  • [redux] useDispatch的两种用法
  • OCR图片中文字识别(Tess4j)
  • Lua开发环境如何安装?保姆级教程
  • 大数据-268 实时数仓 - ODS层 将 Kafka 中的维度表写入 DIM
  • Java编程规约:集合处理
  • 线性变换在机器学习中的应用实例
  • 深入AIGC领域:ChatGPT开发者获取OpenAI API Key的实用指南
  • 公司一个bug引出的对象判空、空指针异常话题之NUll、isEmpty()和“”区别
  • 【华为OD-E卷 - Linux发行版的数量 100分(python、java、c++、js、c)】
  • 【开源免费】基于SpringBoot+Vue.JS保密信息学科平台(JAVA毕业设计)
  • 电脑文件msvcp110.d丢失的解决方法
  • Transformer算法实现IMDB文本分类任务和WMT14机器翻译任务
  • 数据库进阶教程之存储过程(万字详解)
  • 021-spring-springmvc-组件