Qt动态修改svg文件属性

目录

      • 前言
      • 1、加载svg文件
      • 2、动态修改svg属性
      • 3、添加自定义图元

前言

Qt支持加载svg格式的图片,svg是Scalable Vector Graphics的缩写,即可缩放的矢量图像,它是一种基于XML的语言,用于描述二维矢量图形,这种格式的文件具有边缘清晰、文件体积小、传输方便的特点。我们可以通过svg展示复杂的图形场景,这些场景一般由美术设计人员提供编辑好的svg文件,有时还需要根据实际业务变化动态地改变场景中某个图元的位置、颜色、大小等属性。本文总结了加载svg文件,动态修改svg文件属性,及向场景中添加新的图元的方法。

1、加载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;
}

2、动态修改svg属性

svg文件已经可以加载并显示了,那么如何修改svg中图元的属性呢?在前面的介绍中,我们知道svg文件是用xml语言来描述的,要改其中的属性值,其实就是改xml文件中某个元素的属性。下面是一个svg文件的xml源码。



  Example cubic02 - cubic Bezier commands in path data
  Picture showing examples of "C" and "S" commands,
        along with annotations showing the control points
        and end points

  

  
  
  
  
  
  
  
  
  M100,200 C100,100 400,100 400,200

  
  
  
  
  
  
  
  
  M100,500 C25,400 475,400 400,500

  
  
  
  
  
  
  
  
  M100,800 C175,700 325,700 400,800

  
  
  
  
  
  
  
  
  M600,200 C675,100 975,100 900,200

  
  
  
  
  
  
  
  
  M600,500 C600,350 900,650 900,500

  
  
  
  
  
  
  
  
  
  
  
  
  
  M600,800 C625,700 725,700 750,800
  S875,900 900,800

从上面的源码我们可以看到每个元素都有几个属性,而这些属性都可以通过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);

查找目标节点时需要递归遍历所有节点来找出目标节点。

3、添加自定义图元

为了满足特定业务需求,只是展示和修改svg文件还不够,还要能动态的在视图中添加和删除图元,因为svg文件是通过QGraphicsView显示的,因此我们可以利用QGraphicsItem的子类来实现自定义图元,然后添加到场景中。为了方便可以定义一组接口添加特定图元,接口如下

addLine();
addRect();
addEllipse();
addText();
...

QGraphicsItem的子类常用的有下面几种:

  • QGraphicsRectItem //用于添加矩形
  • QGraphicsEllipseItem//用于添加圆形
  • QGraphicsLineItem//用于添加线
  • QGraphicsPixmapItem//用于添加图片
  • QGraphicsTextItem//用于添加文本

以上为本文全部内容,有疑问的朋友欢迎留言讨论!

你可能感兴趣的:(C++,qt,c++)