Есть ли у библиотеки tksvg возможность прочитать svg напрямую из кода, а не из файла?

Есть ли у библиотеки tksvg возможность прочитать svg напрямую из кода, а не из файла? Если да, то как?

Нашел пример в PyQt5, есть ли что-то подобное в tksvg или tkinter?

def iconFromBase64(base_64):
    pixmap = QtGui.QPixmap()
    pixmap.loadFromData(QtCore.QByteArray.fromBase64(base_64), "SVG")
    icon = QtGui.QIcon(pixmap)
    return icon
...
self.svg_str = """
    <svg width="210pt" height="210pt" viewBox="0 0 210 210">....</svg>
"""
svg_base64_str = b64encode(self.svg_str.encode('utf-8'))      
self.icon = iconFromBase64(svg_base64_str)
self.pb.setIcon(self.icon)
...

Ответы (1 шт):

Автор решения: GrAnd

У PhotoImage() есть аргумент data, через который передаются данные для создания картинки. Для бинарных форматов это base64-encoded содержимое файлов. А для SVG - это содержимое самого файла (ибо оно и так текст).

from tkinter import *
import tksvg

svg="""
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="617" height="316">
<defs>
    <radialGradient id="g" cx="549.29" cy="159.12" r="127" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.65 -1.52 1.4 .601129 -26.35 869.29)">
        <stop offset="0" stop-color="#f00" stop-opacity=".27"/>
        <stop offset="1" stop-color="#f00"/>
    </radialGradient>
    <radialGradient id="h" cx="492.86" cy="379.51" r="184.96" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.945 .042 -0.043 .988 43.598 -15.991)">
        <stop offset=".5"/>
        <stop offset=".75"/>
        <stop offset=".88" stop-opacity=".72"/>
        <stop offset=".94" stop-opacity=".51"/>
        <stop offset=".97" stop-opacity=".33"/>
        <stop offset="1" stop-opacity="0"/>
    </radialGradient>
    <radialGradient id="k" cx="449.13" cy="345.23" r="184.96" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.06 0 0 1 -30.44 2)">
        <stop offset="0" stop-color="#fa4"/>
        <stop offset=".5" stop-color="#c3791f"/>
        <stop offset="1" stop-color="#935000"/>
    </radialGradient>
</defs>
<g fill-opacity=".5" stroke-width="4">
    <circle cx="108" cy="108.5" r="100" fill="#0ff" stroke="#0ff"/>
    <circle cx="157.3" cy="209.5" r="100" fill="#ff0" stroke="#ff0"/>
    <circle cx="209.2" cy="109.5" r="100" fill="#f0f" stroke="#f0f"/>
</g>
<rect x="357.2" y="7.53" width="250" height="150" rx="41.429" fill="url(#g)" stroke="#000" stroke-width="4" stroke-dasharray="8 4"/>
<text x="405.11" y="106.51" font-family="Bitstream Vera Sans" font-size="72" font-style="oblique" font-weight="700" fill="#fff" fill-opacity=".5" stroke="#000" stroke-width="3" stroke-dasharray="6 3">SVG</text>
<g transform="matrix(.4033 0 0 .4034 284.7118 53.5686)">
    <path fill="url(#h)" transform="translate(25.72 42.14)" d="M675.82 379.51A182.96 182.96 0 1 0 309.89 379.51 182.96 182.96 0 1 0 675.82 379.51"/>
    <path fill="url(#k)" transform="translate(3 1)" d="M675.82 379.51A182.96 182.96 0 1 0 309.89 379.51 182.96 182.96 0 1 0 675.82 379.51"/>
    <path d="M448.21 203.84C450.36 204.63 453.75 205.95 456.34 207.72 458.94 209.49 460.71 211.6 460.84 214 461.16 219.5 462.73 224.23 456.31 234.22 449.89 244.21 435.16 259.08 402.75 282.44 341.89 326.3 327.7 419.11 324.83 445.46L327.94 453.22C327.94 453.22 336.06 335.44 405.09 285.69 437.69 262.19 452.72 247.17 459.66 236.38 466.59 225.58 465.12 218.64 464.84 213.75 464.61 209.57 461.69 206.56 458.59 204.44 457.31 203.56 455.95 202.87 454.65 202.24L448.21 203.84"/>
    <path d="M509.02 198.03C499.53 209.87 477.92 245.51 465.16 336.75 449.4 449.43 450.71 546.83 450.92 557.84L454.94 558.75C454.94 558.75 452.44 456.6 469.13 337.28 482.75 239.88 506.43 206.86 513.9 198.46 513.9 198.46 509.02 198.03 509.02 198.03"/>
    <path d="M556.69 211.63C547.04 211.81 537.02 214.52 529.97 222.91 520.74 233.89 520.92 245.76 524.5 256.19 528.08 266.61 534.88 275.93 538.97 282.88 541.2 286.67 547.46 295.58 555.44 309.19 563.42 322.8 573.03 340.98 581.72 362.78 599.1 406.39 612.73 464.47 601.94 529.59 601.94 529.59 606.57 526.08 606.57 526.08 616.26 461.74 602.64 404.43 585.44 361.28 576.65 339.24 566.93 320.89 558.88 307.16 550.82 293.42 544.35 284.15 542.41 280.84 538.14 273.59 531.59 264.51 528.28 254.88 524.97 245.24 524.71 235.41 533.03 225.5 541.18 215.8 554.2 214.66 565.56 216.13 576.92 217.59 586.26 221.52 586.26 221.52 586.26 221.52 568.5 212.56 568.5 212.56 567.64 212.42 566.98 212.27 566.09 212.16 563.09 211.77 559.9 211.56 556.69 211.63"/>
    <path d="M458.16 224.97C424.33 226.02 399.2 233.81 381.5 242.41 376.06 245.05 371.36 247.88 367.29 250.52 362.72 255.08 357.49 260.81 350.56 269.41 350.56 269.41 360.3 257.15 383.25 246 406.2 234.85 442.22 224.98 494.53 230.38 599.18 241.17 643.21 296.98 675.72 347 675.72 347 673.38 336.37 673.38 336.37 641.03 288.32 594.99 236.7 494.94 226.38 481.69 225.01 469.43 224.62 458.16 224.97"/>
</g>
</svg>
"""

root = Tk()
img = tksvg.SvgImage(data=svg)
frm = Label(root, image=img)
frm.pack(fill=BOTH)
root.mainloop()

Можно, конечно, и в base64 хранить, если хочется.

from tkinter import *
import tksvg
import base64

root = Tk()

data="PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNjE3IiBoZWlnaHQ9IjMxNiI+CjxkZWZzPgoJPHJhZGlhbEdyYWRpZW50IGlkPSJnIiBjeD0iNTQ5LjI5IiBjeT0iMTU5LjEyIiByPSIxMjciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KC42NSAtMS41MiAxLjQgLjYwMTEyOSAtMjYuMzUgODY5LjI5KSI+CgkJPHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZjAwIiBzdG9wLW9wYWNpdHk9Ii4yNyIvPgoJCTxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI2YwMCIvPgoJPC9yYWRpYWxHcmFkaWVudD4KCTxyYWRpYWxHcmFkaWVudCBpZD0iaCIgY3g9IjQ5Mi44NiIgY3k9IjM3OS41MSIgcj0iMTg0Ljk2IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCguOTQ1IC4wNDIgLTAuMDQzIC45ODggNDMuNTk4IC0xNS45OTEpIj4KCQk8c3RvcCBvZmZzZXQ9Ii41Ii8+CgkJPHN0b3Agb2Zmc2V0PSIuNzUiLz4KCQk8c3RvcCBvZmZzZXQ9Ii44OCIgc3RvcC1vcGFjaXR5PSIuNzIiLz4KCQk8c3RvcCBvZmZzZXQ9Ii45NCIgc3RvcC1vcGFjaXR5PSIuNTEiLz4KCQk8c3RvcCBvZmZzZXQ9Ii45NyIgc3RvcC1vcGFjaXR5PSIuMzMiLz4KCQk8c3RvcCBvZmZzZXQ9IjEiIHN0b3Atb3BhY2l0eT0iMCIvPgoJPC9yYWRpYWxHcmFkaWVudD4KCTxyYWRpYWxHcmFkaWVudCBpZD0iayIgY3g9IjQ0OS4xMyIgY3k9IjM0NS4yMyIgcj0iMTg0Ljk2IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgxLjA2IDAgMCAxIC0zMC40NCAyKSI+CgkJPHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmE0Ii8+CgkJPHN0b3Agb2Zmc2V0PSIuNSIgc3RvcC1jb2xvcj0iI2MzNzkxZiIvPgoJCTxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzkzNTAwMCIvPgoJPC9yYWRpYWxHcmFkaWVudD4KPC9kZWZzPgo8ZyBmaWxsLW9wYWNpdHk9Ii41IiBzdHJva2Utd2lkdGg9IjQiPgoJPGNpcmNsZSBjeD0iMTA4IiBjeT0iMTA4LjUiIHI9IjEwMCIgZmlsbD0iIzBmZiIgc3Ryb2tlPSIjMGZmIi8+Cgk8Y2lyY2xlIGN4PSIxNTcuMyIgY3k9IjIwOS41IiByPSIxMDAiIGZpbGw9IiNmZjAiIHN0cm9rZT0iI2ZmMCIvPgoJPGNpcmNsZSBjeD0iMjA5LjIiIGN5PSIxMDkuNSIgcj0iMTAwIiBmaWxsPSIjZjBmIiBzdHJva2U9IiNmMGYiLz4KPC9nPgo8cmVjdCB4PSIzNTcuMiIgeT0iNy41MyIgd2lkdGg9IjI1MCIgaGVpZ2h0PSIxNTAiIHJ4PSI0MS40MjkiIGZpbGw9InVybCgjZykiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtZGFzaGFycmF5PSI4IDQiLz4KPHRleHQgeD0iNDA1LjExIiB5PSIxMDYuNTEiIGZvbnQtZmFtaWx5PSJCaXRzdHJlYW0gVmVyYSBTYW5zIiBmb250LXNpemU9IjcyIiBmb250LXN0eWxlPSJvYmxpcXVlIiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjZmZmIiBmaWxsLW9wYWNpdHk9Ii41IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMyIgc3Ryb2tlLWRhc2hhcnJheT0iNiAzIj5TVkc8L3RleHQ+CjxnIHRyYW5zZm9ybT0ibWF0cml4KC40MDMzIDAgMCAuNDAzNCAyODQuNzExOCA1My41Njg2KSI+Cgk8cGF0aCBmaWxsPSJ1cmwoI2gpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNS43MiA0Mi4xNCkiIGQ9Ik02NzUuODIgMzc5LjUxQTE4Mi45NiAxODIuOTYgMCAxIDAgMzA5Ljg5IDM3OS41MSAxODIuOTYgMTgyLjk2IDAgMSAwIDY3NS44MiAzNzkuNTEiLz4KCTxwYXRoIGZpbGw9InVybCgjaykiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMgMSkiIGQ9Ik02NzUuODIgMzc5LjUxQTE4Mi45NiAxODIuOTYgMCAxIDAgMzA5Ljg5IDM3OS41MSAxODIuOTYgMTgyLjk2IDAgMSAwIDY3NS44MiAzNzkuNTEiLz4KCTxwYXRoIGQ9Ik00NDguMjEgMjAzLjg0QzQ1MC4zNiAyMDQuNjMgNDUzLjc1IDIwNS45NSA0NTYuMzQgMjA3LjcyIDQ1OC45NCAyMDkuNDkgNDYwLjcxIDIxMS42IDQ2MC44NCAyMTQgNDYxLjE2IDIxOS41IDQ2Mi43MyAyMjQuMjMgNDU2LjMxIDIzNC4yMiA0NDkuODkgMjQ0LjIxIDQzNS4xNiAyNTkuMDggNDAyLjc1IDI4Mi40NCAzNDEuODkgMzI2LjMgMzI3LjcgNDE5LjExIDMyNC44MyA0NDUuNDZMMzI3Ljk0IDQ1My4yMkMzMjcuOTQgNDUzLjIyIDMzNi4wNiAzMzUuNDQgNDA1LjA5IDI4NS42OSA0MzcuNjkgMjYyLjE5IDQ1Mi43MiAyNDcuMTcgNDU5LjY2IDIzNi4zOCA0NjYuNTkgMjI1LjU4IDQ2NS4xMiAyMTguNjQgNDY0Ljg0IDIxMy43NSA0NjQuNjEgMjA5LjU3IDQ2MS42OSAyMDYuNTYgNDU4LjU5IDIwNC40NCA0NTcuMzEgMjAzLjU2IDQ1NS45NSAyMDIuODcgNDU0LjY1IDIwMi4yNEw0NDguMjEgMjAzLjg0Ii8+Cgk8cGF0aCBkPSJNNTA5LjAyIDE5OC4wM0M0OTkuNTMgMjA5Ljg3IDQ3Ny45MiAyNDUuNTEgNDY1LjE2IDMzNi43NSA0NDkuNCA0NDkuNDMgNDUwLjcxIDU0Ni44MyA0NTAuOTIgNTU3Ljg0TDQ1NC45NCA1NTguNzVDNDU0Ljk0IDU1OC43NSA0NTIuNDQgNDU2LjYgNDY5LjEzIDMzNy4yOCA0ODIuNzUgMjM5Ljg4IDUwNi40MyAyMDYuODYgNTEzLjkgMTk4LjQ2IDUxMy45IDE5OC40NiA1MDkuMDIgMTk4LjAzIDUwOS4wMiAxOTguMDMiLz4KCTxwYXRoIGQ9Ik01NTYuNjkgMjExLjYzQzU0Ny4wNCAyMTEuODEgNTM3LjAyIDIxNC41MiA1MjkuOTcgMjIyLjkxIDUyMC43NCAyMzMuODkgNTIwLjkyIDI0NS43NiA1MjQuNSAyNTYuMTkgNTI4LjA4IDI2Ni42MSA1MzQuODggMjc1LjkzIDUzOC45NyAyODIuODggNTQxLjIgMjg2LjY3IDU0Ny40NiAyOTUuNTggNTU1LjQ0IDMwOS4xOSA1NjMuNDIgMzIyLjggNTczLjAzIDM0MC45OCA1ODEuNzIgMzYyLjc4IDU5OS4xIDQwNi4zOSA2MTIuNzMgNDY0LjQ3IDYwMS45NCA1MjkuNTkgNjAxLjk0IDUyOS41OSA2MDYuNTcgNTI2LjA4IDYwNi41NyA1MjYuMDggNjE2LjI2IDQ2MS43NCA2MDIuNjQgNDA0LjQzIDU4NS40NCAzNjEuMjggNTc2LjY1IDMzOS4yNCA1NjYuOTMgMzIwLjg5IDU1OC44OCAzMDcuMTYgNTUwLjgyIDI5My40MiA1NDQuMzUgMjg0LjE1IDU0Mi40MSAyODAuODQgNTM4LjE0IDI3My41OSA1MzEuNTkgMjY0LjUxIDUyOC4yOCAyNTQuODggNTI0Ljk3IDI0NS4yNCA1MjQuNzEgMjM1LjQxIDUzMy4wMyAyMjUuNSA1NDEuMTggMjE1LjggNTU0LjIgMjE0LjY2IDU2NS41NiAyMTYuMTMgNTc2LjkyIDIxNy41OSA1ODYuMjYgMjIxLjUyIDU4Ni4yNiAyMjEuNTIgNTg2LjI2IDIyMS41MiA1NjguNSAyMTIuNTYgNTY4LjUgMjEyLjU2IDU2Ny42NCAyMTIuNDIgNTY2Ljk4IDIxMi4yNyA1NjYuMDkgMjEyLjE2IDU2My4wOSAyMTEuNzcgNTU5LjkgMjExLjU2IDU1Ni42OSAyMTEuNjMiLz4KCTxwYXRoIGQ9Ik00NTguMTYgMjI0Ljk3QzQyNC4zMyAyMjYuMDIgMzk5LjIgMjMzLjgxIDM4MS41IDI0Mi40MSAzNzYuMDYgMjQ1LjA1IDM3MS4zNiAyNDcuODggMzY3LjI5IDI1MC41MiAzNjIuNzIgMjU1LjA4IDM1Ny40OSAyNjAuODEgMzUwLjU2IDI2OS40MSAzNTAuNTYgMjY5LjQxIDM2MC4zIDI1Ny4xNSAzODMuMjUgMjQ2IDQwNi4yIDIzNC44NSA0NDIuMjIgMjI0Ljk4IDQ5NC41MyAyMzAuMzggNTk5LjE4IDI0MS4xNyA2NDMuMjEgMjk2Ljk4IDY3NS43MiAzNDcgNjc1LjcyIDM0NyA2NzMuMzggMzM2LjM3IDY3My4zOCAzMzYuMzcgNjQxLjAzIDI4OC4zMiA1OTQuOTkgMjM2LjcgNDk0Ljk0IDIyNi4zOCA0ODEuNjkgMjI1LjAxIDQ2OS40MyAyMjQuNjIgNDU4LjE2IDIyNC45NyIvPgo8L2c+Cjwvc3ZnPg=="
svg = base64.b64decode(data.encode('ascii'))
img = tksvg.SvgImage(data=svg)
frm = Label(root, image=img)
frm.pack(fill=BOTH)
root.mainloop()
→ Ссылка