QT/PyQT/PySide 通过富文本形式实现关键词高亮

news2024/11/25 3:07:10

因为本质上都是QT,所以我标题带了QT,这个思路是没问题的,就是用C++得换个语言。

最开始想根据之前一篇博客的思路进行高亮

PyQT/PySide 文本浏览器跳转到指定行,并高亮指定行_qt 指定行高亮_Toblerone_Wind的博客-CSDN博客icon-default.png?t=N4P3https://blog.csdn.net/qq_42276781/article/details/127093403突然想到,QT中的文本浏览器可以设置成HTML的富文本格式,可以解析HTML语法,从而实现关键词高亮。例如,在HTML中,如果想让一个词apple变成红色,只需将原文本由apple替换为

<font color="red">apple</font>

<div style="color:red">apple</div>

这里在文本格式化类中实现了一个高亮函数,来高亮指定的关键词

import html
import re

class TextFormatter():
    __replacement = r'<font color="red">\1</font>' # 替换后保留原单词的大小写
    __keywords = ['TODO','FIXME','HACK','XXX','WORKAROUND']

    def highlight_keywords(self, text:str) -> str:
        # 转义特定字符,防止HTML误解析
        text = html.escape(text) 
        for keyword in self.__keywords:
            # 匹配时不考虑大小写,如需考虑移除re.IGNORECASE即可
            pattern = re.compile(f'({re.escape(keyword)})', re.IGNORECASE) 
            text = pattern.sub(self.__replacement, text)
        return text.strip()

highlight_keywords 函数内部,我们首先使用 html.escape 对文本进行转义,以确保字符的兼容性。然后,针对每个关键词,我们使用正则表达式进行替换操作,将匹配到的关键词用 <font color="red">关键词</font> 标签包裹起来以实现高亮效果。

使用正则表达式模式 re.compile(f'({re.escape(keyword)})', re.IGNORECASE) 来匹配指定单词,并且在替换时通过\1 保留原单词的大小写。

re.escape(keyword) 用于转义特殊字符,re.IGNORECASE 参数用于忽略大小写。然后,使用 pattern.sub(self.__replacement, text) 进行替换操作,将匹配到的关键词替换为 <font color="red">关键词</font> 。

完整代码

from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from sys import argv
import html
import re

class TextFormatter():
    __replacement = r'<font color="red">\1</font>' # 替换后保留原单词的大小写
    __keywords = ['TODO','FIXME','HACK','XXX','WORKAROUND']

    def highlight_keywords(self, text:str) -> str:
        # 转义特定字符,防止HTML误解析
        text = html.escape(text) 
        for keyword in self.__keywords:
            # 匹配时不考虑大小写,如需考虑移除re.IGNORECASE即可
            pattern = re.compile(f'({re.escape(keyword)})', re.IGNORECASE) 
            text = pattern.sub(self.__replacement, text)
        return text.strip()


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(300, 250)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.formLayout = QFormLayout(self.centralwidget)
        self.formLayout.setObjectName(u"formLayout")
        self.textBrowser = QTextBrowser(self.centralwidget)
        self.textBrowser.setObjectName(u"textBrowser")
        self.textBrowser.setLineWrapMode(QTextEdit.NoWrap)
        self.textBrowser.setReadOnly(False)
        font = QFont()
        font.setFamily(u"Arial")
        font.setPointSize(22)
        self.textBrowser.setFont(font)
        self.textBrowser.setHtml(u"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:'Consolas'; font-size:20pt; font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>")
        self.formLayout.setWidget(0, QFormLayout.SpanningRole, self.textBrowser)
        MainWindow.setCentralWidget(self.centralwidget)
        self.retranslateUi(MainWindow)
        QMetaObject.connectSlotsByName(MainWindow)
    # setupUi
 
    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))

        text = 'TODO is a food todo'                        # 文本
        text = TextFormatter().highlight_keywords(text)     # 高亮关键词
        self.textBrowser.setText(text)                      # 导入textBrowser
    # retranslateUi
 
 
if __name__ == "__main__":
    app = QApplication(argv)   # 创建应用程序
    mainWindow = QMainWindow() # 创建窗口
    ui = Ui_MainWindow()
    ui.setupUi(mainWindow)
    mainWindow.show()          # 显示窗口
    exit(app.exec_())          # 运行程序直到关闭

效果,文本是TODO is a food todo,高亮显示时不改变原单词的大小写

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/599335.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 设备树文件手动编译的 Makefile

前言 通过了解 Linux 设备树的编译方法&#xff0c;手动写了一个可以把 dts、dtsi、设备树依赖头文件等编译为设备树 dtb 的 Makefile Makefile 如下 mkfile_path : $(abspath $(lastword $(MAKEFILE_LIST))) cur_makefile_path : $(dir $(mkfile_path))DIR_ROOT : $(cur_ma…

十三届蓝桥杯国赛2022

会得噶 A 2022B 钟表C 卡牌D 最大数字dfsF 费用报销&#xff08;不是根据收据个数&#xff0c;而是根据日期dp)H 机房&#xff08;最近公共祖先lca&#xff09;I 齿轮J 搬砖&#xff08;贪心01背包&#xff09; A 2022 #include <bits/stdc.h> using namespace std; int …

Openlayers如何设置米作为作为圆形的真实半径,解决圆形半径跟随地图缩放同时缩放的失真问题

专栏目录: OpenLayers入门教程汇总目录 前言 相信找到这篇文章的同学肯定遇到了Openlayers直接设置圆形半径( radius)单位不准确的问题,而且失真严重。这是因为默认圆形半径设置的是浏览器像素大小,而不是真实地理信息中的半径长度。那么怎么进行转换成我们现实中的“米…

python+vue校园快递代取系统的设计与实现3i0v9

开发语言&#xff1a;Python 框架&#xff1a;django/flask Python版本&#xff1a;python3.7.7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;PyCharm 本系统名为“基于vue快递代取系统”&#xff0c;系统主要适用于毕业设计&#xff0c;不…

【数据分享】1929-2022年全球站点的逐日最高气温(Shp\Excel\12000个站点)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01; 之前我们分享过1929-2022年全球气象站…

高通滤波学习(opencv)

以下代码参考视频解析 这段代码使用了二维FFT变换对输入图像进行频域处理&#xff0c;并设计了一个简单的高通滤波器。 前两行使用了numpy库中的fft2函数对输入图像image进行二维傅里叶变换&#xff08;FFT&#xff09;。接着&#xff0c;fft_shift函数将转化后的频谱数据fft…

什么是DOM和BOM?

一、什么是DOM DOM 全称是 Document Object Model&#xff0c;也就是文档对象模型。提供操作页面元素的方法和属性&#xff0c;是HTML和XML的API&#xff0c;DOM把整个页面规划成由节点层级构成的文档。 DOM 树 DOM树是Web页面的模型&#xff0c;当浏览器加载一个Web页面时&am…

A Framework for Evaluating Gradient Leakage Attacks in Federated Learning

联邦学习中梯度泄漏攻击评估框架 摘要&#xff1a; 针对问题&#xff1a;从客户端向联邦服务器共享本地参数更新也可能容易受到梯度泄漏攻击&#xff0c;并侵犯客户端关于其训练数据的隐私。 提出了一个原则性框架&#xff0c;用于评估和比较不同形式的客户端隐私泄露攻击。…

路径规划算法:基于纵横交叉优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于纵横交叉优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于纵横交叉优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化…

Eclipse导入项目的配置步骤说明

1.数据库创建并导入 &#xff08;1&#xff09;打开navicat&#xff0c;右击&#xff0c;选择创建数据库&#xff0c;进入新建数据库页面&#xff0c;输入数据库名称。我这里创建的是report数据库。 &#xff08;2&#xff09;右击自己创建的数据库&#xff0c;选择运行sql文件…

【C++】STL——stack OJ练习

文章目录 1. 最小栈思路分析AC代码拓展思维 2. 栈的压入、弹出序列思路讲解AC代码 3. 逆波兰表达式求值思路讲解AC代码拓展&#xff1a;中缀表达式如何转后缀 这篇文章我们来做几道stack相关的OJ题&#xff0c;练习一下stack的使用。 1. 最小栈 先来看第一道题——&#xff1a…

【人工智能】常见问题以及解答

1 什么是人工智能 人工智能&#xff08;Artificial Intelligence, AI&#xff09;是一门涉及计算机科学、数学、心理学、哲学等多个领域的交叉学科&#xff0c;旨在研究如何使计算机能够像人一样地思考、学习和行动。 在过去几十年中&#xff0c;人工智能技术得到了广泛的应用…

LNMP部署

LNMP部署 一、安装Nginx服务二、安装mysql服务三、安装配置PHP解析环境四、部署 Discuz&#xff01;社区论坛 Web 应用五、fpm参数优化 LNMP架构&#xff1a; LNMP代表的就是&#xff1a;Linux系统下NginxMySQLPHP这种网站服务器架构Linux是一类Unix计算机操作系统的统称&#…

【P47】JMeter JSON断言(JSON Assertion)

文章目录 一、JSON断言&#xff08;JSON Assertion&#xff09;参数说明二、准备工作三、测试计划设计3.1、Assert JSON Path exists3.2、Additionally assert value3.3、Expect null3.4、Invert assertion &#xff08;will fail if above conditions met&#xff09; 一、JSO…

双链表、循环链表、静态链表

目录 一、双链表1、为什么要引入双链表2、双链表的插入操作3、双链表的插入操作 二、循环链表1、循环单链表2、循环双链表 三、静态链表 一、双链表 1、为什么要引入双链表 单链表结点中只有一个指向其后继的指针&#xff0c;使得单链表只能从头结点依次顺序地向后遍历。要访…

数据治理核心保障数据质量监控开源项目Apache Griffin分享

文章目录 概述定义为何要做数据质量监控基本概念特性架构 安装Docker部署Docker 镜像批处理使用Docker 镜像流处理使用UI界面操作 概述 定义 Apache Griffin 官网地址 https://griffin.apache.org/ 源码release最新版本0.6.0 Apache Griffin 官网文档地址 https://griffin.apa…

MySQL学习(联结,组合查询,全文本搜索)

联结 SQL最强大的功能之一就是能在数据检索查询的执行中联结表&#xff1b; 关系表 为什么要使用关系表&#xff1f; 使用关系表可以储存数据不重复&#xff0c;从而不浪费时间和空间&#xff1b;如果有数据信息变动&#xff0c;只需更新一个表中的单个记录&#xff0c;相关…

研发工程师玩转Kubernetes——Node失效后的Pod的调度实验

在《研发工程师玩转Kubernetes——多Worker Node部署》中&#xff0c;我们创建了Master Node: UbunutA&#xff0c;以及四个Worker Node:UbunutB、UbunutC、UbunutD和UbunutE。本节我们将使用Deployment创建只含有一个nginx的Pod&#xff0c;然后关掉它所在的主机以模拟Node失效…

使用Adobe Acrobat DC对.jpg和.png格式图片转换为.eps图片格式举例

使用Adobe Acrobat DC对.jpg和.png等格式图片转换为.eps图片格式举例 在进行有的文档排版编辑时候&#xff08;比如使用winEdt进行排版CTEX文件时候&#xff09;&#xff0c;需要添加.eps格式的图片&#xff0c;然而电脑中的画图&#xff0c;word和ppt等中无法实现.eps格式图片…

centos7 glib2.0 arm版本的编译

最近在看bluez代码&#xff0c;想编译个例子来玩一下&#xff0c;然后bluez里的例子会用到 libglib-2.0 库里的接口&#xff0c;于是开始了漫长的编译 arm 版本的 libglib-2.0&#xff0c;Linux 系统有时就是很麻烦&#xff0c;要编译一个库&#xff0c;结果发现依赖一大堆库&a…