我对librsvg并不了解,但它似乎自2005年以来就没有更新,因此我倾向于建议使用其他实现方式。
如果您没有依赖于标准库之外的Python库,则可以使用Jython和Batik。这样可以添加事件处理程序,并在渲染后更改DOM。
有关如何在Java中实现此操作的示例,请参见此链接。
以下是到Jython 2.2.1的快速端口(可以运行,但未经全面测试):
from java.awt.event import WindowAdapter;
from java.awt.event import WindowEvent;
from javax.swing import JFrame;
from org.apache.batik.swing import JSVGCanvas;
from org.apache.batik.swing.svg import SVGLoadEventDispatcherAdapter;
from org.apache.batik.swing.svg import SVGLoadEventDispatcherEvent;
from org.apache.batik.script import Window;
from org.w3c.dom import Document;
from org.w3c.dom import Element;
from org.w3c.dom.events import Event;
from org.w3c.dom.events import EventListener;
from org.w3c.dom.events import EventTarget;
class SVGApplication :
def __init__(self) :
class MySVGLoadEventDispatcherAdapter(SVGLoadEventDispatcherAdapter):
def svgLoadEventDispatcherListener(e):
self.document = self.canvas.getSVGDocument();
self.window = self.canvas.getUpdateManager().getScriptingEnvironment().createWindow();
registerListeners();
self.frame.pack();
def windowAdapter(e):
self.canvas.setURI("doc.svg");
self.frame = JFrame(windowOpened = windowAdapter, size=(800, 600));
self.canvas = JSVGCanvas();
self.canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);
self.canvas.addSVGLoadEventDispatcherListener(MySVGLoadEventDispatcherAdapter()) ;
self.frame.getContentPane().add(self.canvas);
self.frame.show()
def registerListeners(self) :
elt = self.document.getElementById("elt-id");
t = elt;
def eventHandler(e):
print e, type(e)
self.window.setTimeout(500,run = lambda : self.window.alert("Delayed Action invoked!"));
t.addEventListener("SVGLoad", false, handleEvent = eventHandler );
t.addEventListener("click", false, handleEvent = eventHandler );
if __name__ == "__main__":
SVGApplication();
使用以下命令运行:
jython -Dpython.path=/usr/share/java/batik-all.jar:/home/jacob/apps/batik-1.7/lib/xml-apis-ext.jar test.py