• 5019阅读
  • 2回复

[讨论]QSvgRenderer无法解析symbol标签吗 [复制链接]

上一主题 下一主题
离线yleesun
 

只看楼主 倒序阅读 楼主  发表于: 2016-03-23
最近在研究QSvgRenderer解析svg文件。定义的的SVG文件如下:
<?xml version='1.0' encoding='UTF-8'?>
<svg width="800" xmlns="http://www.w3.org/2000/svg" height="600"
    xmlns:xlink="http://www.w3.org/1999/xlink" >
<defs>
    <g id="shape2"  >
        <circle cx="0" cy="0" r="25" style="fill:#bf55ec;"/>
    </g>
    <symbol id="shape1" viewBox="0 0 800 600">
        <rect x="50" y="50" width="25" height="50" style="fill:#02ffbb;"/>
    </symbol>
        <rect x="50" y="50" width="25" height="50" style="fill:#02ffbb;"/>
    </symbol>
</defs>
<g id="s1">
    <use xlink:href="#shape2" x="100" y="25" />
</g>  
  <g id="s3">
    <use xlink:href="#shape1" x="150" y="25" />
  </g>
</svg>
解析代码:
QSvgRenderer *renderer = new QSvgRenderer(fileName);

    QGraphicsSvgItem *black = new QGraphicsSvgItem();
    black->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
        black->setSharedRenderer(renderer);
        black->setElementId(QLatin1String("s1"));
        black->setPos(100,25);
    m_sence->addItem(black);

    QGraphicsSvgItem* test2 = new QGraphicsSvgItem();
    test2->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
    test2->setSharedRenderer(renderer);
    test2->setElementId(QLatin1String("s3"));
    test2->setPos(150,25);
    m_sence->addItem(test2);

问题
s1是能正常解析出来的,但是s3确解析 不出来。控制台提示:link shape1 hasn't been detected!
在defs中的<g>标签定义的在<use>的时候可以引用到,<symbol>标签定义的,确引用不到!!
各位,有没有高手有解???

离线abelsky

只看该作者 1楼 发表于: 2016-03-24
离线yleesun

只看该作者 2楼 发表于: 2016-04-12
看来坛子里的高手们太懒了,没有一个赐教的!好吧,问题还得自己想办法解决,在此分享一下,不正确的地方,望高手指正!
解决以上问题有两种方法:
一:把symbol标签替换为g标签。g标签和symbol标签都可以用来定义重复使用的图形,但是symbol功能更加强大,支持viewbox等属性,而g标签不支持。
这种方法,通常viewbox定义从0 0开始,一般不会有问题,但是如果遇到viewbox不是从0 0 开始,那就悲剧了,发现解析后的图元的位置,总是差那一点点。感觉很接近成功了,但是总是差那么一小步。
二:修改qsvg源码,增加对symbol标签的支持。
这个方法比较复杂一些,可以彻底解决问题。不知道qt官方,为什么不提供该功能。
大致原理就是在qsvghandler解析svg的时候,把viewbox属性解析出来,存在qsvgnode的属性中,这个属性也需要自己添加。然后再解析的时候,在根据有没有坐标变换,判断如果使用这个viewbox。

基本就是这样!
快速回复
限100 字节
 
上一个 下一个