我想按名称呈现svg文件的一部分,但在我的生命中,我无法确定如何这样做(使用python+gtk)。
这里是有问题的svg文件:http://david.bellot.free.fr/svg-cards/files/SVG-cards-2.0.1.tar.gz(更新:此文件不再存在,但您可以在http://svg-cards.sourceforge.net/找到它)
在他的网站上,大卫说:
You can draw a card either by rendering the file onto a pixmap and clipping each card manually or by using the card's name through a DOM interface. All cards are embedded into a SVG group.
我不知道他说的DOM接口是什么意思。我做了一些搜索,我发现最好的结果似乎适合我想做的是:
QSvgRenderer *renderer = new QSvgRenderer(QLatin1String("SvgCardDeck.svg"));
QGraphicsSvgItem *black = new QGraphicsSvgItem();
QGraphicsSvgItem *red = new QGraphicsSvgItem();
black->setSharedRenderer(renderer);
black->setElementId(QLatin1String("black_joker"));
red->setSharedRenderer(renderer);
red->setElementId(QLatin1String("red_joker"));
但是请注意,它是针对Qt的,甚至没有用python编写。
这就是我目前所拥有的:
#!/usr/bin/env python
from __future__ import absolute_import
import cairo
import gtk
import rsvg
from xml import xpath
from xml.dom import minidom
window = gtk.Window()
window.set_title("Foo")
window.set_size_request(256, 256)
window.set_property("resizable", False)
window.set_position(gtk.WIN_POS_CENTER)
window.connect("destroy", gtk.main_quit)
window.show()
document = minidom.parse("cards.svg")
element = xpath.Evaluate("//*[@id='1_club']", document)[0]
xml = element.toxml()
svg = rsvg.Handle()
svg.write(xml)
pixbuf = svg.get_pixbuf()
image = gtk.Image()
image.set_from_pixbuf(pixbuf)
image.show()
window.add(image)
gtk.main()
当然没用。
我错过了什么?
用于呈现SVG的GTK库称为RSVG。它有python绑定,但是它们没有文档记录,而且它们没有包装通常在C中用于此目的的
rsvg_handle_get_pixbuf_sub()
和rsvg_handle_render_cairo_sub()
函数。您可以按照Adam Crossland的建议提取XML节点。要渲染它,必须执行以下操作:如果你想把它放在一个
gtk.Image
中,否则就用pixbuf做别的事情。您还可以使用handle.render_cairo(cr)
将其呈现到Cairo上下文,其中cr
是您的Cairo上下文。编辑:
抱歉,我一开始没有仔细阅读python绑定。
_sub()
函数是使用id=
参数实现的,因此您的程序可以归结为:我测试了这个,结果成功了。但是,窗口的大小与整个SVG画布的大小相同,并且被剪裁为屏幕大小(这就是为什么我渲染的是3个菱形而不是角落里的球杆的王牌),所以您仍然需要找到一些方法来裁剪您想要的卡周围的pixbuf,但这不应该太难。
这是我对裁剪空白问题的答案。这是一个粗糙的黑客,但它工作得很好。这也可以作为一个很好的起点,让任何人在python中制作一个纸牌游戏。
我相信他所说的“通过DOM接口”的意思是,由于SVG是XML,您可以在minidom或其他Python XML解析器中加载SVG文件,并用您要查找的特定名称提取XML节点。该XML节点应该表示可以呈现的项。
相关问题 更多 >
编程相关推荐