在Windows中使用python的GTK的rSVG问题

时间:2014-01-24 11:24:37

标签: python linux windows svg gtk

我有一个python脚本,可以在Linux上使用Cairo和GTK来操作SVG文件。 在Linux上,我包含了这个库:

#import rsvg

我很高兴。在Windows上,它有点复杂。我找到了这个页面:http://cairographics.org/cairo_rsvg_and_python_in_windows/ 建议使用给定的代码挂钩到Windows上的GTK dll。这似乎有效,但是glib报告了我无法处理的错误,特别是:

  

GLib-WARNING **:GError设置在先前的GError或未初始化的内存的顶部。   这表示某人的代码中存在错误。在设置之前,必须确保错误为NULL。   覆盖错误消息是:打开文件时出错:没有这样的文件或目录

运行此代码时:

svg_file_name = "c:/test.svg" #also tried "c:\\test.svg" and "file:///c:/test.svg"
handler = rsvg.Handle(svg_file_name)
dim     = handler.get_dimension_data()

我不确定它正在讨论什么文件,因为我似乎无法从glib中获得任何错误细节。我已经尝试了所有SVG文件名的排列。我假设它抱怨该文件,但它可能是GTK内部的东西,我不知道。

我已经尝试连接到glib的DLL并运行g_clear_error(0)以清除错误消息所述的错误堆叠但是根据glib错误报告(https://developer.gnome.org/glib/2.37/glib-Error-Reporting.html#g-clear-error)的文档我需要一个如果我要对它做任何事情,从导致问题的代码处理错误对象 - 从python中,我不知道我是怎么做到的。

欢迎任何关于GTK错误报告和从python中清除的提示。如果没有,如果有人可以建议一个替代SVG渲染库在python for windows中工作,我会很感激。   我已经尝试过CairoSVG,它可以达到某一点,但无法渲染渐变,似乎不允许对SVG数据进行编程操作。

感谢您的时间

3 个答案:

答案 0 :(得分:1)

为什么找不到文件我不知道,但覆盖GError的问题在这里:

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

rsvg_handle_new_from_file()期待指向GError的指针。相反,它会得到一个空字符串,当它需要使用它时非常困惑......这只是不起作用。你可以尝试创建一个GError类yoursefl,有一个例子in this question。这不是完全无足轻重的:如果这不是生产代码,你可以跳过这部分并试图找出找不到文件的原因......

对于找不到文件的问题,当文件在工作目录中时,可以尝试使用“test.svg”,以限制可能出现问题的范围。

答案 1 :(得分:1)

我建议使用GObject Introspection绑定RSVG。在Ubuntu上安装包gir1.2-rsvg-(whatever)。然后使用from gi.repository import Rsvg导入模块。

这些绑定是自动生成的,您根本不必关心GError结构;错误将自动转换为Python异常。

答案 2 :(得分:0)

我设法让错误处理工作。如果有人感兴趣,这里有一个修改版本的this需要在python中获得一个可用的GError对象:

      class rsvgHandle():
            class _GError(Structure):
                _fields_ = [("domain", c_uint32), 
                            ("code", c_int), 
                            ("message", c_char_p)]

            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):
                #l.rsvg_handle_new_from_file.argtypes = [c_char_p, POINTER(POINTER(self._GError))]

                self.path = path                
                error = POINTER(self._GError)()
                print("Path: " + self.path)
                self.handle = l.rsvg_handle_new_from_file(self.path,byref(error))
                if (error != 0):
                    gerr = error.contents
                    print("error:" + str(gerr.message) + " : " + self.path)


            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)

        rsvg = rsvgClass()