我有一个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数据进行编程操作。
感谢您的时间
答案 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()