如何从字符串/xml流在PyQT5中显示SVG图像? [英] How to show SVG image in PyQT5 from string/xml stream?

查看:72
本文介绍了如何从字符串/xml流在PyQT5中显示SVG图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Python3/QT5 应用程序中,我试图显示最初作为字符串构建的 SVG 图像.我需要操作这个 SVG 图像(例如改变它的颜色),所以我的字符串会随着时间的推移而改变.这是一个最小的工作示例:

In a Python3/QT5 application, I'm trying to show a SVG image built originally as a string. I need to manipulate this SVG image (e.g. change its color), so I have the string changing over time. Here is a minimal working example:

import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtSvg import QSvgWidget

svg_str = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="300" height="300" viewBox="0 0 300 300" id="smile" version="1.1">
    <path
        style="fill:#ffaaaa"
        d="M 150,0 A 150,150 0 0 0 0,150 150,150 0 0 0 150,300 150,150 0 0 0 
            300,150 150,150 0 0 0 150,0 Z M 72,65 A 21,29.5 0 0 1 93,94.33 
            21,29.5 0 0 1 72,124 21,29.5 0 0 1 51,94.33 21,29.5 0 0 1 72,65 Z 
            m 156,0 a 21,29.5 0 0 1 21,29.5 21,29.5 0 0 1 -21,29.5 21,29.5 0 0 1 
            -21,-29.5 21,29.5 0 0 1 21,-29.5 z m -158.75,89.5 161.5,0 c 0,44.67 
            -36.125,80.75 -80.75,80.75 -44.67,0 -80.75,-36.125 -80.75,-80.75 z"
    />
</svg>
"""
# ==========================================
with open('smile.svg', 'w') as f:
    f.write(svg_str)
# ==========================================
app = QApplication(sys.argv)
svgWidget = QSvgWidget('smile.svg')
svgWidget.setGeometry(100,100,300,300)
svgWidget.show()
sys.exit(app.exec_())

我的问题是我找不到保存文件的方法,以便从字符串本身实例化 QSvgWidget 对象.我不想随意保存文件,也找不到将 xml 信息直接加载到 QSvgWidget 对象的方法...

My problem is that I couldn't find a way around the need to save the file in order to instantiate a QSvgWidget object from the string itself. I don't want to save files indiscriminately and I couldn't find a way to load xml information directly to a QSvgWidget object...

我找到了一个最接近我的愿望的解决方案,它看起来像这样:

I found a solution closest to my desires, and it looks like this:

import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtSvg import QSvgWidget, QSvgRenderer
from PyQt5.QtCore import QXmlStreamReader
from PyQt5.QtGui import QPainter

svg_str = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="300" height="300" viewBox="0 0 300 300" id="smile" version="1.1">
    <path
        style="fill:#ffaaaa"
        d="M 150,0 A 150,150 0 0 0 0,150 150,150 0 0 0 150,300 150,150 0 0 0 
            300,150 150,150 0 0 0 150,0 Z M 72,65 A 21,29.5 0 0 1 93,94.33 
            21,29.5 0 0 1 72,124 21,29.5 0 0 1 51,94.33 21,29.5 0 0 1 72,65 Z 
            m 156,0 a 21,29.5 0 0 1 21,29.5 21,29.5 0 0 1 -21,29.5 21,29.5 0 0 1 
            -21,-29.5 21,29.5 0 0 1 21,-29.5 z m -158.75,89.5 161.5,0 c 0,44.67 
            -36.125,80.75 -80.75,80.75 -44.67,0 -80.75,-36.125 -80.75,-80.75 z"
    />
</svg>
"""
# ==========================================
class QSvgWidget_from_string(QSvgWidget):
    def __init__(self, strSVG):
        super().__init__()
        self.strSVG = strSVG
    def paintEvent(self, event):
        qp = QPainter()
        qp.begin(self)
        svg_render = QSvgRenderer(QXmlStreamReader(self.strSVG))
        qp.restore()
        svg_render.render(qp)
        qp.end()
# ==========================================
app = QApplication(sys.argv)
svgWidget = QSvgWidget_from_string(svg_str)
svgWidget.setGeometry(100,100,300,300)
svgWidget.show()
sys.exit(app.exec_())

但我并不满意,因为我需要扩展 QSvgWidget 类只是为了从 xml 字符串实例化它.我的问题是:有没有什么办法可以不用QPaintpaintEvent 来做到这一点?

But I'm not satisfied because I need to expand QSvgWidget class just to instantiate it from a xml string. My question is: Is there any way of doing this without having to resort to QPaint and paintEvent?

推荐答案

您可以获得 QSvgWidget 使用的 QSvgRenderer 来渲染 SVG.它允许从文件、字节数组或流加载数据:

You can get the QSvgRenderer used by the QSvgWidget to render the SVG. It allows to load data from a file, byte array or a stream:

import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtSvg import QSvgWidget, QSvgRenderer

svg_str = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="300" height="300" viewBox="0 0 300 300" id="smile" version="1.1">
    <path
        style="fill:#ffaaaa"
        d="M 150,0 A 150,150 0 0 0 0,150 150,150 0 0 0 150,300 150,150 0 0 0 
            300,150 150,150 0 0 0 150,0 Z M 72,65 A 21,29.5 0 0 1 93,94.33 
            21,29.5 0 0 1 72,124 21,29.5 0 0 1 51,94.33 21,29.5 0 0 1 72,65 Z 
            m 156,0 a 21,29.5 0 0 1 21,29.5 21,29.5 0 0 1 -21,29.5 21,29.5 0 0 1 
            -21,-29.5 21,29.5 0 0 1 21,-29.5 z m -158.75,89.5 161.5,0 c 0,44.67 
            -36.125,80.75 -80.75,80.75 -44.67,0 -80.75,-36.125 -80.75,-80.75 z"
    />
</svg>
"""

svg_bytes = bytearray(svg_str, encoding='utf-8')

app = QApplication(sys.argv)
svgWidget = QSvgWidget()
svgWidget.renderer().load(svg_bytes)
svgWidget.setGeometry(100,100,300,300)
svgWidget.show()
sys.exit(app.exec_())

更多信息在这里:http://doc.qt.io/qt-5/qsvgrenderer.html

这篇关于如何从字符串/xml流在PyQT5中显示SVG图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆