【Python、Qt】使用QItemDelegate实现单元格的富文本显示+复选框功能
主打一个 折磨 坑多 陪伴。代码为Python,C++的就自己逐条语句慢慢改吧。
Python代码:
import sys
from types import MethodType
from PyQt5.QtCore import Qt,QPoint,QSize,QRect,QEvent
from PyQt5.QtGui import QStandardItemModel, QStandardItem,QTextDocument,QTextCursor
from PyQt5.QtWidgets import QTreeView,QApplication,QItemDelegate,QStyleclass RichDelegate(QItemDelegate):#使用QItemDelegate进行单元格重绘:https://blog.csdn.net/Loc_Haoclass/article/details/106528047__cboxSize=QSize(14,14)#复选框大小__cboxAlignV=Qt.AlignVCenter#竖直位置(居中)__cboxAlignH=Qt.AlignLeft#水平位置(左对齐)def __init__(self,parent=None,*,align=None,size=None):super().__init__(parent)if(align):self.SetCheckboxAlign(align)if(size):self.SetCheckboxSize(size)def SetCheckboxAlign(self,align):#设置复选框位置alignV=[Qt.AlignTop,Qt.AlignVCenter,Qt.AlignBottom]alignH=[Qt.AlignLeft,Qt.AlignHCenter,Qt.AlignRight]alignV=list(filter(lambda a:int(align) & int(a)!=0,alignV))alignH=list(filter(lambda a:int(align) & int(a)!=0,alignH))alignV.append(Qt.AlignVCenter)alignH.append(Qt.AlignLeft)self.__cboxAlignV=alignV[0]self.__cboxAlignH=alignH[0]def SetCheckboxSize(self,size):#设置复选框大小self.__cboxSize=sizedef editorEvent(self,event,model,opt,index):#处理复选框点击逻辑:https://blog.csdn.net/xbnlkdbxl/article/details/51316424if(event.type()==QEvent.MouseButtonRelease):#仅处理鼠标抬起事件if(event.button()==Qt.LeftButton):#仅处理鼠标左键item=index.model().itemFromIndex(index)if(item.isCheckable()):#仅处理复选框存在的情况rect_cbox=self.__GetRect_Checkbox(opt.rect)if(rect_cbox.contains(event.pos())):#仅复选框被点击时翻转状态item.setCheckState(Qt.Unchecked if item.checkState()==Qt.Checked else Qt.Checked)return Truereturn Falsedef drawCheck(self,ptr,opt,rect,state):#绘制复选框(这里直接默认绘制,有想法的可以改成其他绘制例如画个圈之类的super().drawCheck(ptr,opt,rect,state)#默认绘制的复选框总是正方形def paint(self,ptr,opt,index):style=opt.widget.style() if opt.widget else QApplication.style()style.drawControl(QStyle.CE_ItemViewItem, opt, ptr, opt.widget)#这条语句解决了行选中时背景色不变化的问题:https://blog.csdn.net/gongjianbo1992/article/details/108687172rect=QRect(opt.rect)item=index.model().itemFromIndex(index)if(item.isCheckable()):#绘制复选框:https://blog.csdn.net/xbnlkdbxl/article/details/51316424rect_cbox=self.__GetRect_Checkbox(rect)self.drawCheck(ptr,opt,rect_cbox,item.checkState())#计算剩余位置用于绘制文本内容if(self.__cboxAlignH==Qt.AlignRight):#只调整水平位置(应该不会有人那么异端把复选框放在单元格正中间的吧,不会吧不会吧rect.setRight(rect.right()-rect_cbox.width())else:rect.setLeft(rect.left()+rect_cbox.width())tx=index.data()doc=QTextDocument()doc.setHtml(tx)txDot='...'#替换为省略号testPoint=QPoint(rect.width(), rect.height() / 2)#获取能完整显示的字符个数:https://blog.csdn.net/eiilpux17/article/details/118461445pos = doc.documentLayout().hitTest(testPoint, Qt.ExactHit)if(pos!=-1 and pos !=len(doc.toPlainText())):#不能完全显示的情况下进行字符替换docDot=QTextDocument()docDot.setHtml(txDot)docDot.setDocumentMargin(0)#发现调用该语句后doc.size取值恢复正常:https://cloud.tencent.com/developer/ask/sof/105271901testPoint=QPoint(rect.width()-docDot.size().width(), rect.height() / 2)pos = doc.documentLayout().hitTest(testPoint, Qt.ExactHit)if(pos==-1):pos=0cursor=QTextCursor(doc)cursor.setPosition(pos)# cursor.insertText(txDot)cursor.movePosition(QTextCursor.End, QTextCursor.KeepAnchor)cursor.insertText(txDot,cursor.block().charFormat())LT=rect.bottomLeft()LT.setY(LT.y()-doc.size().height())# LT=rect.topLeft()ptr.save()ptr.translate(LT)ptr.setClipRect(rect.translated(-rect.topLeft()))# doc.setDefaultTextOption(doc.defaultTextOption())doc.drawContents(ptr)ptr.restore()def sizeHint(self,opt,index):#设置行高函数:https://blog.csdn.net/Lutx/article/details/6641353tx=index.data()doc=QTextDocument()doc.setHtml(tx)size=doc.size()return QSize(size.width(),size.height())def __GetRect_Checkbox(self,rect):#返回复选框确切位置alignV=[Qt.AlignTop,Qt.AlignVCenter,Qt.AlignBottom]alignH=[Qt.AlignLeft,Qt.AlignHCenter,Qt.AlignRight]posV=[rect.top(),rect.bottom()]posH=[rect.left(),rect.right()]for nape in [[self.__cboxAlignV,alignV,posV,self.__cboxSize.height()],[self.__cboxAlignH,alignH,posH,self.__cboxSize.width()]]:align,alignLst,pos,width=napeindex=alignLst.index(align)if(index==0):#靠左/靠上pos[1]=pos[0]+widthelif(index==1):#居中pos[0]=pos[0]+int((pos[1]-pos[0]-width)/2)pos[1]=pos[0]+widthelif(index==2):#靠右/靠下pos[0]=pos[1]-widthreturn QRect(posH[0],posV[0],posH[1]-posH[0],posV[1]-posV[0])if __name__ == '__main__':app = QApplication(sys.argv)tv=QTreeView()tv.setModel(QStandardItemModel(tv))model=tv.model()model.appendRow([QStandardItem(d) for d in ['<font color="red" size=3> R3 </font>']])model.appendRow([QStandardItem(d) for d in ['<font color="red" size=5> R5 </font>']])model.appendRow([QStandardItem(d) for d in ['<font color="red" size=7> R7 </font>']])model.appendRow([QStandardItem(d) for d in ['<font color="red" style="font-size:50px"> R50px </font>','<font style="background:#0000FF;font-size:70px">B70px</font>']])model.appendRow([QStandardItem(d) for d in ['<font size=5><sub>bbb</sub><sup>ppp</sup><br><s>SSS</s><i>III</i><u>UUU</u></font><br><font color="red" style="background:#00FFFF;font-size:20pt">R20pt</font>']])model.item(1,0).setCheckable(True)model.item(3,1).setCheckable(True)model.item(4,0).setCheckable(True)rich_1=RichDelegate()rich_2=RichDelegate(align=Qt.AlignBottom|Qt.AlignRight)#复选框右对齐是什么邪道行为,太怪了(感觉除了左居中以外的对齐都是邪道tv.setItemDelegateForRow(0,rich_1)tv.setItemDelegateForRow(1,rich_1)tv.setItemDelegateForRow(2,rich_1)tv.setItemDelegateForRow(3,rich_1)tv.setItemDelegateForRow(4,rich_2)tv.show()sys.exit(app.exec())
运行结果:

补充:
1、我的代码仅完成富文本显示,像是往单元格里塞入按钮、下拉列表亦或是其他控件不在本篇讨论范围之内,有需要的可以参考[CSDN]QStyledItemDelegate单元格数据渲染与编辑、[51CTO]QTableWidget使用setCellWidget设置控件居中显示或是自行搜索其他文章
2、复选框的绘制样式甚至可以自定义,像是画成圆圈或是其他东西,又或是嫌黑色不好看改成紫色绿色啥的,只不过得自己实现就是了,重绘仅需QPainter倒少了挺多麻烦(只不过还是挺麻烦的所以没这需求就没必要自找麻烦
参考资料:
- 使用QItemDelegate显示富文本:[CSDN]https://blog.csdn.net/Loc_Haoclass/article/details/106528047
- QItemDelegate实现CheckBox复选框功能:[CSDN]https://blog.csdn.net/xbnlkdbxl/article/details/51316424
- QStyledItemDelegate单元格数据渲染与编辑:[CSDN]https://blog.csdn.net/gongjianbo1992/article/details/108687172
- 精确获取字符完整显示个数:[CSDN]https://blog.csdn.net/eiilpux17/article/details/118461445
- QItemDelegate单元格设置行高:[CSDN]https://blog.csdn.net/Lutx/article/details/6641353
本文发布于CSDN,未经个人同意不得私自转载:https://blog.csdn.net/weixin_44733774/article/details/133838003
相关文章:
【Python、Qt】使用QItemDelegate实现单元格的富文本显示+复选框功能
主打一个 折磨 坑多 陪伴。代码为Python,C的就自己逐条语句慢慢改吧。 Python代码: import sys from types import MethodType from PyQt5.QtCore import Qt,QPoint,QSize,QRect,QEvent from PyQt5.QtGui import QStandardItemModel, QStandardItem,QTe…...
【JVM】JVM类加载机制
JVM类加载机制 加载双亲委派模型 验证准备解析初始化 JVM的类加载机制,就是把类,从硬盘加载到内存中 Java程序,最开始是一个Java文件,编译成.class文件,运行Java程序,JVM就会读取.class文件,把文件的内容,放到内存中,并且构造成.class类对象 加载 这里的加载是整个类加载的一…...
【面试经典150 | 区间】汇总区间
文章目录 Tag题目来源题目解读解题思路方法一:一次遍历复杂度分析 其他语言python3C 写在最后 Tag 【一次遍历】【数组】【字符串】 题目来源 228. 汇总区间 题目解读 给定一个无重复的升序数组 nums,需要将这个数组按照以下规则进行汇总࿱…...
主流接口测试框架对比
公司计划系统的开展接口自动化测试,需要我这边调研一下主流的接口测试框架给后端测试(主要测试接口)的同事介绍一下每个框架的特定和使用方式。后端同事根据他们接口的特点提出一下需求,看哪个框架更适合我们。 需求 1、接口编写…...
LeetCode 150.逆波兰表达式求值
题目链接 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 题目解析 首先我们需要知道什么是逆波兰表达式,像我们平常遇到的都是中缀表达式,然而逆波兰确实后缀表达式,因此这个题目隐含的意思就是将一个后缀表达式转…...
华为---企业WLAN组网基本配置示例---AC+AP组网
ACAP组网所需的物理条件 1、无线AP---收发无线信号; 2、无线控制器(AC)---用来控制管理多个AP; 3、PoE交换机---能给AP实现网络连接和供电的交换机; 4、授权:默认AC管理的AP数量有限,买授权才能管控更多AP。 WLAN创建…...
循环结构的运用
乘法口诀起源于中国,是古代人进行乘法、除法、开方等运算的基本法则,距今已经有两千多年的历史了,如何运用现代计算机技术快速写出九九乘法表呢? 循环结构可以用来重复执行一条或者多条语句,利用循环结构可以减少源程序…...
深度强化学习第 1 章 机器学习基础
1.1线性模型 线性模型(linear models)是一类最简单的有监督机器学习模型,常被用于简单的机 器学习任务。可以将线性模型视为单层的神经网络。本节讨论线性回归、逻辑斯蒂回归(logistic regression)、 softmax 分类器等…...
第一章 STM32 CubeMX (CAN通信发送)基础篇
第一章 STM32 CubeMX (CAN通信)基础篇 文章目录 第一章 STM32 CubeMX (CAN通信)基础篇STM32中文手册简介简介stm32f1系列CAN的特点CAN连接网络示意图硬件电路CAN波特率计数 一、 STM32 CubeMX设置设置波特率工程目录结构添加CAN驱…...
原子性操作
原子性操作是指一个操作在执行过程中不会被中断,要么全部执行成功,要么全部不执行,不会出现部分执行的情况。原子性操作对于多线程并发编程至关重要,因为它可以确保多个线程之间不会出现竞态条件或数据不一致性。 在计算机科学中…...
论文阅读:Segment Any Point Cloud Sequences by Distilling Vision Foundation Models
目录 概要 Motivation 整体架构流程 技术细节 小结 论文地址:[2306.09347] Segment Any Point Cloud Sequences by Distilling Vision Foundation Models (arxiv.org) 代码地址:GitHub - youquanl/Segment-Any-Point-Cloud: [NeurIPS23 Spotlight]…...
Netty 入门 — 亘古不变的Hello World
这篇文章我们正式开始学习 Netty,在入门之前我们还是需要了解什么是 Netty。 什么是 Netty 为什么很多人都推崇 Java boy 去研究 Netty?Netty 这么高大上,它到底是何方神圣? 用官方的话说:Netty 是一款异步的、基于事…...
idea插件开发javax.net.ssl.SSLException: No PSK available. Unable to resume.
idea插件开发,编译出错 javax.net.ssl.SSLException: No PSK available. Unable to resume.at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:129)at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)at java.base/sun.security.ssl.…...
Selenium的WebDriver操作页面的超时或者元素重叠引起的ElementClickInterceptedException
超时 处理由页面加载引起的超时是在使用 Selenium 进行自动化测试中常见的任务。页面加载可能因网络速度慢、页面复杂性或异步操作而导致超时。以下是一些处理页面加载超时的方法: 1.设置隐式等待时间: 使用 implicitly_wait 方法可以设置隐式等待时间…...
oracle数据库的缓存设置
Oracle缓存由两个参数控制SGA_TARGET和PGA_AGGREGATE_TARGET,设置了这两个参数,其他的基本内存部分都由Oracle自动配置为最优值,这也是Oracle推荐的方式。 SGA_TARGET 和PGA_AGGREGATE_TARGET是动态参数,可以在不重启数据库的情况…...
算法通关村第一关-链表青铜挑战笔记
欢迎来到 : 第一关青铜关 java如何创建链表链表怎么增删改查 我们先了解链表 单链表的概念 我们从简单的创建和增删改查开始. 链表的概念 线性表分为顺序表(数组组成)和链表(节点组成) . 链表又分: 单向 双向有哨兵节点 无哨兵节点循环 不循环 链表是一种物理存储单…...
✔ ★【备战实习(面经+项目+算法)】 10.15学习时间表
✔ ★【备战实习(面经项目算法)】 坚持完成每天必做如何找到好工作1. 科学的学习方法(专注!效率!记忆!心流!)2. 每天认真完成必做项,踏实学习技术 认真完成每天必做&…...
pytorch 训练时raise EOFError EOFError
训练到一半时获取验证数据报错 报错代码 imgs next(iter(val_dataloader)) val_dataloader DataLoader(ImageDataset("data/%s" % opt.dataset_name, transforms_transforms_, unalignedTrue, mode"test"),batch_size5,shuffleTrue,num_workers2,)def …...
node.js+NPM包管理器+Webpack打包工具+前端项目搭建
javascript运行环境(无需依赖html文件) BFF,服务于前端的后端 官网下载安装,node -v查看是否安装成功 ①、创建一个01.js文件 //引入http模块 const httprequire(http)//创建服务器 http.createServer(function(request,respo…...
PCL点云处理之基于FPFH特征的全局配准流程具体实现(二百二十一)
PCL点云处理之基于FPFH特征的全局配准流程具体实现(二百二十一) 一、算法介绍二、算法实现1.代码2.效果一、算法介绍 PCL点云库提供的多种工具,可以组合为一套完整的点云配准流程,这里选择FPFH特征,进行具体的配准流程实现,主要内容包括点云读取、点云法线计算、点云特征…...
掌控AMD Ryzen性能:5步精通SMUDebugTool硬件调试技巧
掌控AMD Ryzen性能:5步精通SMUDebugTool硬件调试技巧 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://git…...
在线考试系统如何实现随机组卷
在现代教育和企业培训中,考试是评估学习效果、提升培训效率的重要工具。然而,传统的固定试卷模式存在诸多问题:题目重复率高、考试公平性难以保障、人工管理成本高。随着在线培训的发展,尤其是在大规模培训场景下,随机…...
picdone
链接:https://pan.quark.cn/s/849b9ab09851支持对图片进行基础的裁剪、格式转换,背景去除、尺寸调整、体积压缩、添加水印、证件照处理的功能,处理好后可直接下载PNG到本地。...
基于Next.js 14与Sanity构建高性能个人博客:全栈技术栈解析与实践
1. 项目概述:一个现代、高性能的个人博客系统 最近在折腾个人博客,发现了一个非常亮眼的开源项目——CaliCastle/cali.so。这不仅仅是一个博客模板,更是一个集成了当前前端最佳实践的完整个人网站解决方案。原作者Cali(Calvin&am…...
Python使用Matplotlib绘制基础可视化图表
在Python中进行数据可视化,最常用且功能强大的库是 Matplotlib。它可以帮助你轻松绘制出柱状图、折线图、饼图、散点图、直方图、箱线图、热力图、雷达图等。在开始之前,请确保你已经安装了Matplotlib库。如果没有,可以在终端或命令行中运行以…...
图片重复检测革命:AntiDupl.NET如何智能清理你的数字相册
图片重复检测革命:AntiDupl.NET如何智能清理你的数字相册 【免费下载链接】AntiDupl A program to search similar and defect pictures on the disk 项目地址: https://gitcode.com/gh_mirrors/an/AntiDupl 在数字摄影普及的今天,我们每个人的硬…...
PostgreSQL17高级特性实战
PostgreSQL 17 高级特性实战:JSON 增强、增量备份与逻辑复制深度指南 🐘 PostgreSQL 17 是 2024 年最重要的数据库版本更新之一——JSON 能力大幅增强、备份恢复效率翻倍、逻辑复制全面升级。本文带你深入每个新特性的实战用法。 📌 前言 PostgreSQL 一直是「最先进」的开…...
别再让树莓派吃灰了!用腾讯云轻量服务器+frp,5分钟搞定远程SSH和VNC访问
树莓派远程访问实战:5分钟解锁SSH与VNC的轻量级方案 每次打开抽屉看到积灰的树莓派,总有种辜负了这片单板计算机潜力的愧疚感。其实只需一台基础配置的云服务器,就能让闲置设备变身24小时在线的开发工作站。本文将用最简步骤实现:…...
085、命令行工具开发:argparse模块实战笔记
085、命令行工具开发:argparse模块实战笔记 昨天帮同事调试一个数据清洗脚本,问题出在参数解析上。脚本接收三个输入路径,结果他少传了一个参数,程序直接崩溃报“IndexError”。这种体验太糟糕了——用户不知道哪里错了,也不知道该怎么用。这就是为什么我们需要专业的命令…...
别再只用流水灯了!用Arduino和74HC595驱动数码管/点阵屏的完整教程
从流水灯到智能显示:74HC595驱动数码管与点阵屏的实战指南 在创客社区里,74HC595移位寄存器几乎成了"流水灯"的代名词——无数入门教程用它来演示如何用少量IO口控制多颗LED。但当你真正需要构建一个电子钟、温湿度显示器或简易信息板时&#…...
