1

I understand that Stackoverflow is for help with code, but I figured I'd ask anyways.

I found from the post here that it is possible to put a .svg file into a tkinter window, but after days of searching, I still can't find any place where I could install cairo and rsvg from.

I am currently using Windows 10 with python 3.6.

EDIT:

I have found out how to install cairo and rsvg. Cairo is working but rsvg is not. I have managed to put SVGs in Tkinter with cairo and not rsvg, though. For anyone curious about this, you may want to check post out: Putting .SVG images into tkinter Frame.

Thanks in advance.

Andoo
  • 734
  • 6
  • 22

1 Answers1

1

Edit: Ok, so pip won't work for installing pycairo. Found that out. And the other options haven't worked for me either. I am about to be away from my computer, but I'll give you some of the things I found.
This This and
This

Sorry I couldn't be more help. Hope you figure it out!

First, use pip install pycairo

Unfortunately, rsvg is unavailable for windows, but cairographics.org have a simple wrapper.

Save the following as rsvg.py in the same folder as your script:

#some code to give rsvg.render_cairo(ctx) ability
#on windows.
import os
try:
    import rsvg
    WINDOWS=False
except ImportError:
    print"Warning, could not import 'rsvg'"
    if os.name == 'nt':
        print "Detected windows, creating rsvg."
        #some workarounds for windows

        from ctypes import *

        l=CDLL('librsvg-2-2.dll')
        g=CDLL('libgobject-2.0-0.dll')
        g.g_type_init()

        class rsvgHandle():
            class RsvgDimensionData(Structure):
                _fields_ = [("width", c_int),
                            ("height", c_int),
                            ("em",c_double),
                            ("ex",c_double)]

            class PycairoContext(Structure):
                _fields_ = [("PyObject_HEAD", c_byte * object.__basicsize__),
                            ("ctx", c_void_p),
                            ("base", c_void_p)]

            def __init__(self, path):
                self.path = path
                error = ''
                self.handle = l.rsvg_handle_new_from_file(self.path,error)


            def get_dimension_data(self):
                svgDim = self.RsvgDimensionData()
                l.rsvg_handle_get_dimensions(self.handle,byref(svgDim))
                return (svgDim.width,svgDim.height)

            def render_cairo(self, ctx):
                ctx.save()
                z = self.PycairoContext.from_address(id(ctx))
                l.rsvg_handle_render_cairo(self.handle, z.ctx)
                ctx.restore()



        class rsvgClass():
            def Handle(self,file):
                return rsvgHandle(file)

In your script, do from rsvg import * and when you need to use it, run:

rC = rsvgClass()
h = rC.Handle("YOUR-FILE-HERE.svg")
s = cairo.ImageSurface(cairo.FORMAT_ARGB32, 100, 100)
ctx = cairo.Context(s)
h.render_cairo(ctx)
  • 1
    you cant name the file rsvg.py, due to the fact that it `try`s to `import` the actual rsvg module that would be installed on any other person's machine except windows... naming the file rsvg.py and then `try`ing to import rsvg means that you would be `try`ing to import your rsvg.py file and not the library that would be installed on other machines. So the class would never be created. Learned that the hard way. – Shmack Feb 25 '21 at 17:03