Qt支持加载svg格式的图片,svg是Scalable Vector Graphics的缩写,即可缩放的矢量图像,它是一种基于XML的语言,用于描述二维矢量图形,这种格式的文件具有边缘清晰、文件体积小、传输方便的特点。我们可以通过svg展示复杂的图形场景,这些场景一般由美术设计人员提供编辑好的svg文件,有时还需要根据实际业务变化动态地改变场景中某个图元的位置、颜色、大小等属性。本文总结了加载svg文件,动态修改svg文件属性,及向场景中添加新的图元的方法。
Qt提供了在QWidget和其他绘制设备上渲染和显示SVG图形的类QGraphicsSvgItem。将 QGraphicsSvgItem 对象添加到QGraphicsView 中来显示svg文件。QGraphicsView可以使用QWidget或QGLWidget作为其视口。这里我们继承QGraphicsView,来实现一个SvgViewer类,
其中openFile接口用来设置要显示的svg文件。
bool SvgViewer::openFile(const QString &fileName)
{
QGraphicsScene *s = scene();
QScopedPointer svgItem(new QGraphicsSvgItem(fileName));
if (!svgItem->renderer()->isValid())
return false;
s->clear();
resetTransform();
m_svgItem = svgItem.take();
m_svgItem->setFlags(QGraphicsItem::ItemClipsToShape);
m_svgItem->setCacheMode(QGraphicsItem::NoCache);
m_svgItem->setZValue(0);
s->addItem(m_svgItem);
return true;
}
svg文件已经可以加载并显示了,那么如何修改svg中图元的属性呢?在前面的介绍中,我们知道svg文件是用xml语言来描述的,要改其中的属性值,其实就是改xml文件中某个元素的属性。下面是一个svg文件的xml源码。
从上面的源码我们可以看到每个元素都有几个属性,而这些属性都可以通过xml解析器来访问。如果我们给每一个元素分配一个id,再通过id查找到对应的元素,然后修改它的属性,就可以实现动态修改属性的目的,最后重新加载svg源码就可以看到更新后的效果了。伪代码如下:
QDomDocument doc;
QFile file();
doc.setContent(file);
QDomElement ele = doc.documentElement(); //通过遍历节点根据节点id找到需要操作的节点,修改其属性。
QString svgXml = doc.toString();//将修改后的xml对象转为字符串
m_svgItem->renderer()->load(xml);//用QGraphicsSvgItem的渲染器重新加载xml源码,更新显示
为了方便修改任意元素的属性,可以添加新的方法,如这里修改元素的颜色添加下面一组方法
setColorById(id, color);
setColorByClass(className, color);
setColorByGroupId(groupId, color);
查找目标节点时需要递归遍历所有节点来找出目标节点。
为了满足特定业务需求,只是展示和修改svg文件还不够,还要能动态的在视图中添加和删除图元,因为svg文件是通过QGraphicsView显示的,因此我们可以利用QGraphicsItem的子类来实现自定义图元,然后添加到场景中。为了方便可以定义一组接口添加特定图元,接口如下
addLine();
addRect();
addEllipse();
addText();
...
QGraphicsItem的子类常用的有下面几种:
以上为本文全部内容,有疑问的朋友欢迎留言讨论!