QT5开发及实例学习之十八显示Qt5 SVG格式图片

  SVG 的英文全称是 Scalable Vector Graphics,即可缩放的矢量图形。它是由万维网络联盟 ( World Wide Web Consortium, W3C ) 在 2000 年 8 月制定的一种新的二维矢量图形格式,也是规范中的网格矢量图形标准,是一个开放的图形标准。
  SVG 格式的特点如下:
 (1)基于 XML。
 (2)采用文本来描述对象。
 (3)具有交互性和动态性。
 (4)完全支持 DOM。
  SVG 相对于 GIF、JPEG 格式的优势是,SVG 是一种矢量图形格式,比 GIF、JPEG 等栅格格式具有众多优势,如文件小,对于网络而言,下载速度快;可任意缩放而不会破坏图像的清晰度和细节;图像中的文字独立于图像,文字保留可编辑和可搜寻的状态,也没有字体限制,用户系统即使没有安装某一种字体,也可以看到与制作时完全相同的画面等。正是基于其格式的各种优点及开放性,SVG 得到了众多组织和知名厂商的支持与认可,因此能够迅速地开发和推广应用。
  Qt 为 SVG 格式图片的显示与生成提供了专门的 QtSvg 模块,此模块中包含了与 SVG 图片相关的所有类,主要有 QSvgWidget、QSvgRender 和 QGraphicsSvgItem。

  通过利用 QSvgWidget 类和 QSvgRender 类实现一个 SVG 图片浏览器,显示以 " .svg " 结尾的文件以介绍 SVG 格式图片显示的方法。
  绘图工具框架:
在这里插入图片描述
(1)SvgWidget 类继承自 QSvgWidget 类,主要显示 SVG 图片。
  SvgWidget 构造函数获得本窗体的 QSvgRenderer 对象;具体代码如下:

SvgWidget::SvgWidget(QWidget *parent):QSvgWidget(parent)
{
    render = renderer();
}

(2)鼠标滚轮的响应事件,使 SVG 图片能够通过鼠标滚轮的滚动进行缩放;具体代码如下:

void SvgWidget::wheelEvent(QWheelEvent *e)
{
    const double diff = 0.1;            //(a)
    QSize size = render->defaultSize(); //(b)
    int width = size.width();
    int height = size.height();
    if(e->delta() > 0)                  //(c)
    {
        //对图片的长、宽值进行处理,放大一定的比例
        width = int(this->width() + this->width()*diff);
        height = int(this->height() + this->height()*diff);
    }
    else
    {
        //对图片的长、宽值进行处理,缩小一定的比例
        width = int(this->width() - this->width()*diff);
        height = int(this->height() - this->height()*diff);
    }
    resize(width, height);              //利用新的长、宽值对图片进行resize()操作
}

 (a)diff 的值表示每次滚轮滚动一定的值,图片大小改变的比例。
 (b)该行及下面两行代码用于获取图片显示区的尺寸,以便进行下一步的缩放操作。
 (c)利用 QWheelEvent 的 delta() 函数获得滚轮滚动的距离值,通过此值来判断滚轮滚动的方向。若 delta() 值大于零,则表示滚轮向前(远离用户的方向)滚动;若小于零,则表示向后(靠近用户的方向)滚动。
  鼠标滚动事件,滚轮没滚动 1° 相当于移动 8° ,而常见的滚轮鼠标拨动一下滚动的角度为 15°,因此滚轮拨动一下相当于移动了 120(=15*8)°。

(3)SvgWindow 类继承自 QScrollArea 类,是一个带滚动条的显示区域。在 SvgWindow 类实现中包含 SvgWidget 类的头文件。SvgWindow 类使图片在放大到超过主窗口大小时,能够通过拖拽滚动条的方式进行查看。
  SvgWindow 类的构造函数,构造 SvgWidget 对象,并调用 QScrollArea 类的 setWidget() 函数设置滚动区域的窗体,使 svgWidget 成为 SvgWindow 的子窗口。
  具体代码如下:

SvgWindow::SvgWindow(QWidget *parent):QScrollArea(parent)
{
    svgWidget = new SvgWidget();
    setWidget(svgWidget);
}

(4)当主窗口中对文件进行了选择或修改时,将调用 setFile() 函数设置新的文件,具体代码如下:

void SvgWindow::setFile(QString fileName)
{
    svgWidget->load(fileName);                  //(a)
    QSvgRenderer *render = svgWidget->renderer();
    svgWidget->resize(render->defaultSize());   //(b)
}

 (a)将新的 SVG 文件加载到 svgWidget 中进行显示。
 (b)使 svgWidget 窗体按 SVG 图片的默认尺寸进行显示。

(5)当鼠标键被按下时,对 mousePressPos 和 scrollBarValuesOnMousePress 进行初始化,QScrollArea 类的 herizontalScrollBar() 和 verticalScrollBar() 函数可以分别获得 svgWindow 的水平滚动条和垂直滚动条。具体代码如下:

void SvgWindow::mousePressEvent(QMouseEvent *event)
{
    mousePressPos = event->pos();
    scrollBarValuesOnMousePress.rx() = horizontalScrollBar()->value();
    scrollBarValuesOnMousePress.ry() = verticalScrollBar()->value();
    event->accept();
}

(6)当鼠标键被按下并拖拽鼠标时触发 mouseMoveEvent() 函数,通过滚动条的位置设置实现图片拖拽的效果,具体代码如下:

void SvgWindow::mouseMoveEvent(QMouseEvent *event)
{
    horizontalScrollBar()->setValue(scrollBarValuesOnMousePress.x() - event->pos().x() + mousePressPos.x());//设置水平滚动条新位置
    verticalScrollBar()->setValue(scrollBarValuesOnMousePress.y() - event->pos().y() + mousePressPos.y());  //设置垂直滚动条新位置
    horizontalScrollBar()->update();
    verticalScrollBar()->update();
    event->accept();
}

(7)主窗口 MainWindow 继承自 QMainWindow 类,包含一个菜单栏,其中有一个“文件”菜单条,包含一个“打开”菜单项。
  在 MainWindow 构造函数中,创建一个 SvgWindow 对象作为主窗口的中央窗体。具体代码如下:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setWindowTitle(QObject::tr("SVG Viewer"));
    createMenu();
    svgWindow = new SvgWindow();
    setCentralWidget(svgWindow);
}

(8)创建菜单栏,具体代码如下:

void MainWindow::createMenu()
{
    QMenu *fileMenu = menuBar()->addMenu(QObject::tr("文件"));
    QAction *openAct = new QAction(QObject::tr("打开"), this);
    connect(openAct, SIGNAL(triggered()), this, SLOT(slotOpenFile()));
    fileMenu->addAction(openAct);
}

(9)通过标准文件对话框选择 SVG 文件,并调用 SvgWindow 的 setFile() 函数将选择的文件名传递给 svgWindow 进行显示,具体代码如下:

void MainWindow::slotOpenFile()
{
    QString name = QFileDialog::getOpenFileName(this, "打开", "/", "svg files(*.svg)");
    svgWindow->setFile(name);
}

补充、Qt 5 SVG 格式图片显示:概念解析

XML

  Qt 的 XML 模块支持两种 XML 解析方法:DOM 和 SAX。
  其中,DOM 方法将 XML 文件表示为一棵树,以便随机访问其中的节点,但消耗内存相对多一些。而 SAX 是一种事件驱动的 XML API,其速度快,但不便于随机访问任意节点。因此,通常根据实际应用选择合适的解析方法。
  这里只介绍 DOM 的使用方法。
  文档对象模型 (Document Object Model, DOM) 是 W3C 开发的独立于平台和语言的接口,它可以使程序和脚本动态地存取和更新 XML 文档的内容、结构和风格。
  DOM 在内存中将 XML 文件表示为一棵树,用户通过 API 可以随意地访问树的任意节点内容。在 Qt 中,XML 文档自身用 QDomDocument 表示,所有的节点类都从 QDomNode 继承。
  SVG 文件是利用 XML 表示的矢量图形文件,每种图形都用 XML 标签表示。
  例如,在 SVG 中画折线的标签如下:

	<polyline fill="none"  stroke="#888888"  stroke-width="2"  points="100, 200, 100, 100"/>
  • polyline:表示绘制折线。
  • fill:表示填充。
  • stroke:表示画笔颜色。
  • stroke-width:表示画笔宽度。
  • points:表示折线的点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值