首页 > 其他分享 >如何在Pyqt中渲染使用svggraphicsItem的SVG字形?

如何在Pyqt中渲染使用svggraphicsItem的SVG字形?

时间:2024-09-04 10:52:41浏览次数:15  
标签:use nl dom SVG self Pyqt return svggraphicsItem def

在使用 PyQt 构建应用程序时,有时需要在图形用户界面中渲染 SVG(可缩放矢量图形)文件,特别是当你需要显示图标或自定义字体时。QGraphicsSvgItem 是 PyQt 提供的一个类,用于在 QGraphicsViewQGraphicsScene 中渲染 SVG 图像。然而,如果你想使用 SVG 字形或通过编程方式生成矢量图形,QSvgRendererQGraphicsSvgItem 是两个关键的组件。

如何在Pyqt中渲染使用svggraphicsItem的SVG字形?_SVG

1、问题背景

在 Pyqt 中使用 svggraphicsItem 渲染 SVG 字形时,可能会遇到一些问题。例如,由 Cairo 生成的 SVG 文件在 Pyqt 中无法正确显示,其中使用了 glyphs 图标,在 Pyqt 中似乎无法显示。

2、解决方案

为了解决此问题,提供了一个函数 convertSVG(self, file) 来将 glyphs 转换为 SVG 路径,以便文件能够正常渲染。此函数需要嵌入到类中或将 self 删除才能在其他地方使用。

def convertSVG(self, file):
    dom = self._getsvgdom(file)
    print(dom)
    self._switchGlyphsForPaths(dom)
    self._commitSVG(file, dom)

以下是一些其他函数,用于在 Pyqt 中渲染 SVG 字形:

def _commitSVG(self, file, dom):
    f = open(file, 'w')
    dom.writexml(f)
    f.close()

def _getsvgdom(self, file):
    print('getting DOM model')
    import xml.dom
    import xml.dom.minidom as mini
    f = open(file, 'r')
    svg = f.read()
    f.close()
    dom = mini.parseString(svg)
    return dom

def _getGlyphPaths(self, dom):
    symbols = dom.getElementsByTagName('symbol')
    glyphPaths = {}
    for s in symbols:
        pathNode = [p for p in s.childNodes if 'tagName' in dir(p) and p.tagName == 'path']
        glyphPaths[s.getAttribute('id')] = pathNode[0].getAttribute('d')
    return glyphPaths

def _switchGlyphsForPaths(self, dom):
    glyphs = self._getGlyphPaths(dom)
    use = self._getUseTags(dom)
    for glyph in glyphs.keys():
        print(glyph)
        nl = self.makeNewList(glyphs[glyph].split(' '))
        u = self._matchUseGlyphs(use, glyph)
        for u2 in u:
            print(u2, 'brefore')
            self._convertUseToPath(u2, nl)
            print(u2, 'after')

def _getUseTags(self, dom):
    return dom.getElementsByTagName('use')

def _matchUseGlyphs(self, use, glyph):
    matches = []
    for i in use:
        print(i.getAttribute('xlink:href'))
        if i.getAttribute('xlink:href') == '#'+glyph:
            matches.append(i)
    print(matches)
    return matches

def _convertUseToPath(self, use, strokeD):
    ## strokeD is a list of lists of strokes to make the glyph
    newD = self.nltostring(self.resetStrokeD(strokeD, use.getAttribute('x'), use.getAttribute('y')))
    use.tagName = 'path'
    use.removeAttribute('xlink:href')
    use.removeAttribute('x')
    use.removeAttribute('y')
    use.setAttribute('style', 'fill: rgb(0%,0%,0%); stroke-width: 0.5; stroke-linecap: round; stroke-linejoin: round; stroke: rgb(0%,0%,0%); stroke-opacity: 1;stroke-miterlimit: 10; ')
    use.setAttribute('d', newD)

def makeNewList(self, inList):
    i = 0
    nt = []
    while i < len(inList):
        start = i + self.listFind(inList[i:], ['M', 'L', 'C', 'Z'])
        end = start + self.listFind(inList[start+1:], ['M', 'L', 'C', 'Z', '', ' '])
        nt.append(inList[start:end+1])
        i = end + 1
    return nt

def listFind(self, x, query):
    for i in range(len(x)):
        if x[i] in query:
            return i
    return len(x)

def resetStrokeD(self, strokeD, x, y):  # convert a list of strokes to xy coords
    nsd = []
    for i in strokeD:
        nsd.append(self.resetXY(i, x, y))
    return nsd

def resetXY(self, nl, x, y):  # convert a list of strokes to xy coords
    nl2 = []
    for i in range(len(nl)):
        if i == 0:
            nl2.append(nl[i])
        elif i%2:  # it's odd
            nl2.append(float(nl[i]) + float(x))
        elif not i%2:  # it's even
            nl2.append(float(nl[i]) + float(y))
        else:
            print(i, nl[i], 'error')
    return nl2

def nltostring(self, nl):  # convert a colection of nl's to a string
    col = []
    for l in nl:
        templ = []
        for c in l:
            templ.append(str(c))
        templ = ' '.join(templ)
        col.append(templ)
    return ' '.join(col)

通过以上方法,你可以在 PyQt 应用程序中成功渲染 SVG 字形,并通过图形视图与用户进行交互。

标签:use,nl,dom,SVG,self,Pyqt,return,svggraphicsItem,def
From: https://blog.51cto.com/u_13488918/11916858

相关文章

  • PyQt5
    一、介绍PyQt基于QT库的python封装,是一个图形用户界面(GUI)工具包,允许用户使用python语言创建桌面应用程序。目前,不同版本中,PyQt5是较为流行的版本,支持python2.7和python3.x。PyQt支持两种开发方式,可视化和编程化。-编程式创建界面无需多说,pip安装成功以后,有较深基础功底......
  • 【python】PyQt5中富文本框QTextEdit的详细教程与应用实战
    ✨✨欢迎大家来到景天科技苑✨✨......
  • 【PyQt5 应用程序】PyQt基础组件:按钮
    在任何图形用户界面(GUI)应用程序中,按钮是最基本也是最频繁使用的组件之一。它们是用户与应用程序交互的主要方式之一。在PyQt中,按钮可以通过QPushButton类创建,它提供了丰富的功能,包括显示文本、图像,以及响应点击事件。本节将引导你了解如何在PyQt应用中创建和使用按钮,并通过......
  • 使用pyqt5记录
    方便的windows上位机制作软件图形界面制作使用QtDesigner软件完成图形界面的制作,信号绑定之类的图形界面文件转py文件 使用该命令,在windows命令端下将.ui文件转成.py文件python-mPyQt5.uic.pyuicuntitled.ui-ountitled.py//文件自己修改可选,方便的python文件编辑......
  • Yololov5+Pyqt5+Opencv 实时城市积水报警系统
    在现代城市生活中,积水问题不仅影响交通和人们的日常生活,还可能对城市基础设施造成潜在的威胁。为了快速、准确地识别和应对积水问题,使用计算机视觉技术进行智能积水检测成为一个重要的解决方案。在这篇博客中,我将带你一步步实现一个基于YOLOv5的积水检测系统,帮助你轻松应对城市......
  • 利用机器学习模型实时检测恶意软件——打造一款基于PyQt5的智能检测系统
    引言随着科技的发展,恶意软件的种类和复杂性也在日益增加。传统的防护手段往往难以应对新型的攻击手段,而机器学习技术的应用为恶意软件检测带来了新的可能性。本文将带领大家一起探索如何通过Python和PyQt5,构建一个实时恶意软件检测系统。这个系统不仅可以分析数据,还能训练机器......
  • PyQt5 / PySide 2 + Pywin32 自定义标题栏窗口 + 还原 Windows 原生窗口边框特效(2)
    前言:已修复上一篇文章中提到的Bug,增加状态切换动画:PyQt5/PySide2+Pywin32自定义标题栏窗口+还原Windows原生窗口边框特效-CSDN博客https://blog.csdn.net/2402_84665876/article/details/141487635?spm=1001.2014.3001.5501仍然存在的问题:打开窗口时窗口标题栏......
  • PYQT5的环境配置
    一。前言系统:win11最近开始了解qt,想用qt来做一些实践项目,于是先开始了环境配置。最开始想分别配置python的环境和qt环境python环境配置简单,输入官网:python.org  找到download,在里面找到对应的python版本下载就行了,我下载的版本是3.12.5 应该是最新版本,下载完成后打开......
  • PyQt5 / PySide 2 + Pywin32 自定义标题栏窗口 + 还原 Windows 原生窗口边框特效
    Bug:当窗口不处于顶层时,如果点击窗体试图将其置于顶层,窗体自带的白边框会突然显示,最长两秒。完整性:尚未添加窗口状态的过渡动画和淡入、淡出动画。其他问题:由于Qt官方在版本6去掉了QtWin,目前暂未找到PyQt6/PySide6的解决方案。准备工作:在同目录下放四张照片:m......
  • PyQt5简介
    PyQt是Qt框架的Python语言实现,由RiverbankComputing开发,是最强大的GUI库之一。PyQt提供了一个设计良好的窗口控件集合,每一个PyQt控件都对应一个Qt控件,因此PyQt的API接口与Qt的API接口很接近,但PyQt不再使用QMake系统和Q_OBJECT宏。PyQt5提供GPL版和商业版证书,自由开发者可以使用......