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

【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&#xff0c;C的就自己逐条语句慢慢改吧。 Python代码&#xff1a; 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题目来源题目解读解题思路方法一&#xff1a;一次遍历复杂度分析 其他语言python3C 写在最后 Tag 【一次遍历】【数组】【字符串】 题目来源 228. 汇总区间 题目解读 给定一个无重复的升序数组 nums&#xff0c;需要将这个数组按照以下规则进行汇总&#xff1…...

主流接口测试框架对比

公司计划系统的开展接口自动化测试&#xff0c;需要我这边调研一下主流的接口测试框架给后端测试&#xff08;主要测试接口&#xff09;的同事介绍一下每个框架的特定和使用方式。后端同事根据他们接口的特点提出一下需求&#xff0c;看哪个框架更适合我们。 需求 1、接口编写…...

LeetCode 150.逆波兰表达式求值

题目链接 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题目解析 首先我们需要知道什么是逆波兰表达式&#xff0c;像我们平常遇到的都是中缀表达式&#xff0c;然而逆波兰确实后缀表达式&#xff0c;因此这个题目隐含的意思就是将一个后缀表达式转…...

华为---企业WLAN组网基本配置示例---AC+AP组网

ACAP组网所需的物理条件 1、无线AP---收发无线信号&#xff1b; 2、无线控制器(AC)---用来控制管理多个AP&#xff1b; 3、PoE交换机---能给AP实现网络连接和供电的交换机&#xff1b; 4、授权&#xff1a;默认AC管理的AP数量有限&#xff0c;买授权才能管控更多AP。 WLAN创建…...

循环结构的运用

乘法口诀起源于中国&#xff0c;是古代人进行乘法、除法、开方等运算的基本法则&#xff0c;距今已经有两千多年的历史了&#xff0c;如何运用现代计算机技术快速写出九九乘法表呢&#xff1f; 循环结构可以用来重复执行一条或者多条语句&#xff0c;利用循环结构可以减少源程序…...

深度强化学习第 1 章 机器学习基础

1.1线性模型 线性模型&#xff08;linear models&#xff09;是一类最简单的有监督机器学习模型&#xff0c;常被用于简单的机 器学习任务。可以将线性模型视为单层的神经网络。本节讨论线性回归、逻辑斯蒂回归&#xff08;logistic regression&#xff09;、 softmax 分类器等…...

第一章 STM32 CubeMX (CAN通信发送)基础篇

第一章 STM32 CubeMX &#xff08;CAN通信&#xff09;基础篇 文章目录 第一章 STM32 CubeMX &#xff08;CAN通信&#xff09;基础篇STM32中文手册简介简介stm32f1系列CAN的特点CAN连接网络示意图硬件电路CAN波特率计数 一、 STM32 CubeMX设置设置波特率工程目录结构添加CAN驱…...

原子性操作

原子性操作是指一个操作在执行过程中不会被中断&#xff0c;要么全部执行成功&#xff0c;要么全部不执行&#xff0c;不会出现部分执行的情况。原子性操作对于多线程并发编程至关重要&#xff0c;因为它可以确保多个线程之间不会出现竞态条件或数据不一致性。 在计算机科学中…...

论文阅读:Segment Any Point Cloud Sequences by Distilling Vision Foundation Models

目录 概要 Motivation 整体架构流程 技术细节 小结 论文地址&#xff1a;[2306.09347] Segment Any Point Cloud Sequences by Distilling Vision Foundation Models (arxiv.org) 代码地址&#xff1a;GitHub - youquanl/Segment-Any-Point-Cloud: [NeurIPS23 Spotlight]…...

Netty 入门 — 亘古不变的Hello World

这篇文章我们正式开始学习 Netty&#xff0c;在入门之前我们还是需要了解什么是 Netty。 什么是 Netty 为什么很多人都推崇 Java boy 去研究 Netty&#xff1f;Netty 这么高大上&#xff0c;它到底是何方神圣&#xff1f; 用官方的话说&#xff1a;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 进行自动化测试中常见的任务。页面加载可能因网络速度慢、页面复杂性或异步操作而导致超时。以下是一些处理页面加载超时的方法&#xff1a; 1.设置隐式等待时间&#xff1a; 使用 implicitly_wait 方法可以设置隐式等待时间…...

oracle数据库的缓存设置

Oracle缓存由两个参数控制SGA_TARGET和PGA_AGGREGATE_TARGET&#xff0c;设置了这两个参数&#xff0c;其他的基本内存部分都由Oracle自动配置为最优值&#xff0c;这也是Oracle推荐的方式。 SGA_TARGET 和PGA_AGGREGATE_TARGET是动态参数&#xff0c;可以在不重启数据库的情况…...

算法通关村第一关-链表青铜挑战笔记

欢迎来到 : 第一关青铜关 java如何创建链表链表怎么增删改查 我们先了解链表 单链表的概念 我们从简单的创建和增删改查开始. 链表的概念 线性表分为顺序表(数组组成)和链表(节点组成) . 链表又分: 单向 双向有哨兵节点 无哨兵节点循环 不循环 链表是一种物理存储单…...

✔ ★【备战实习(面经+项目+算法)】 10.15学习时间表

✔ ★【备战实习&#xff08;面经项目算法&#xff09;】 坚持完成每天必做如何找到好工作1. 科学的学习方法&#xff08;专注&#xff01;效率&#xff01;记忆&#xff01;心流&#xff01;&#xff09;2. 每天认真完成必做项&#xff0c;踏实学习技术 认真完成每天必做&…...

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运行环境&#xff08;无需依赖html文件&#xff09; BFF&#xff0c;服务于前端的后端 官网下载安装&#xff0c;node -v查看是否安装成功 ①、创建一个01.js文件 //引入http模块 const httprequire(http)//创建服务器 http.createServer(function(request,respo…...

PCL点云处理之基于FPFH特征的全局配准流程具体实现(二百二十一)

PCL点云处理之基于FPFH特征的全局配准流程具体实现(二百二十一) 一、算法介绍二、算法实现1.代码2.效果一、算法介绍 PCL点云库提供的多种工具,可以组合为一套完整的点云配准流程,这里选择FPFH特征,进行具体的配准流程实现,主要内容包括点云读取、点云法线计算、点云特征…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

JavaScript 标签加载

目录 JavaScript 标签加载script 标签的 async 和 defer 属性&#xff0c;分别代表什么&#xff0c;有什么区别1. 普通 script 标签2. async 属性3. defer 属性4. type"module"5. 各种加载方式的对比6. 使用建议 JavaScript 标签加载 script 标签的 async 和 defer …...

基于小程序老人监护管理系统源码数据库文档

摘 要 近年来&#xff0c;随着我国人口老龄化问题日益严重&#xff0c;独居和居住养老机构的的老年人数量越来越多。而随着老年人数量的逐步增长&#xff0c;随之而来的是日益突出的老年人问题&#xff0c;尤其是老年人的健康问题&#xff0c;尤其是老年人产生健康问题后&…...