SVG全称Scalable Vector Graphics,即可缩放矢量图。
优点:
- 基于XML。
- 采用文本来描述对象。
- 具有交互性和动态性。
- 完全支持DOM。
- 文件小。
- 任意缩放不破坏图像的清晰度。
- 图像中的文字独立于图像,没有字体限制。
目标:
使用QSvg、QSvgRender等显示一张SVG图像,并进行缩放验证其清晰度。
代码主体结构:
- main.cpp创建SVGTest 。
- SVGtest.cpp构造函数设置标题、创建菜单、创建svgWindow、设置svgWindow为主Widget。
- svgWindow.cpp构造函数创建svgwidget。
- svgwidget.cpp构造函数进行渲染和图像缩放。
.pro
.pro中要加入svg,才能使用相关类模块。
QT += core gui svg
svgtest.h
#ifndef SVGTEST_H
#define SVGTEST_H
#include <QMainWindow>
#include "svgwindow.h"
class SVGTest : public QMainWindow
{
Q_OBJECT
public:
SVGTest(QWidget *parent = nullptr);
~SVGTest();
void creatMenu();
public slots:
void slotOpenFile();
private:
SvgWindow *svgWindow;
};
#endif // SVGTEST_H
svgtest.cpp
serFile()比较关键,将文件名传递给svgWindow。
#include "svgtest.h"
#include <QMenu>
#include <QMenuBar>
#include <QFileDialog>
SVGTest::SVGTest(QWidget *parent)
: QMainWindow(parent)
{
setWindowTitle(tr("SVG Viewer"));
creatMenu();
svgWindow = new SvgWindow;
setCentralWidget(svgWindow);
}
SVGTest::~SVGTest()
{
}
void SVGTest::creatMenu()
{
QMenu * fileMenu = menuBar()->addMenu(tr("文件"));
QAction * openAct = new QAction(tr("打开"),this);
connect(openAct,&QAction::triggered,this,&SVGTest::slotOpenFile);
fileMenu->addAction(openAct);
}
void SVGTest::slotOpenFile()
{
QString name = QFileDialog::getOpenFileName(this,"打开","/","svg files(*.svg)");
svgWindow->setFile(name);
}
svgwidget.h
声明滚轮事件wheelEvent,用于通过滚轮的滑动进行缩放图像。
#ifndef SVGWIDGET_H
#define SVGWIDGET_H
#include <QSvgWidget>
#include <QSvgWidget>
#include <QSvgRenderer>
class SvgWidget : public QSvgWidget
{
Q_OBJECT
public:
SvgWidget(QWidget *parent = 0);
void wheelEvent(QWheelEvent *);
private:
QSvgRenderer *render;
};
#endif // SVGWIDGET_H
svgwidget.cpp
其中滚轮事件的delta()可以获取滚轮的滚动距离值,大于0向前滚动,小于0向后滚动。
滚轮1度=移动8度,常规滚动15度,相当于移动了120个单位(15*8)
#include "svgwidget.h"
#include <QWheelEvent>
SvgWidget::SvgWidget(QWidget *parent):QSvgWidget(parent)
{
render = renderer();
}
void SvgWidget::wheelEvent(QWheelEvent * e)
{
const double diff = 0.1;
QSize size = render->defaultSize();
int width = size.width();
int height = size.height();
if(e->delta() >0){
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);
}
svgwindow.h
#ifndef SVGWINDOW_H
#define SVGWINDOW_H
#include <QScrollArea>
#include "svgwidget.h"
class SvgWindow : public QScrollArea
{
Q_OBJECT
public:
SvgWindow(QWidget * parent = 0);
void setFile(QString);
void mousePressEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
private:
SvgWidget *svgWidget;
QPoint mousePressPos;
QPoint scrollBarValuesOnMousePress;
};
#endif // SVGWINDOW_H
svgwindow.cpp
#include "svgwindow.h"
#include <QMouseEvent>
#include <QScrollBar>
SvgWindow::SvgWindow(QWidget *parent):QScrollArea(parent)
{
svgWidget = new SvgWidget;
setWidget(svgWidget);
}
void SvgWindow::setFile(QString fileName)
{
svgWidget->load(fileName);
QSvgRenderer *render = svgWidget->renderer();
svgWidget->resize(render->defaultSize());
}
void SvgWindow::mousePressEvent(QMouseEvent *e)
{
mousePressPos = e->pos();
scrollBarValuesOnMousePress.rx() = horizontalScrollBar()->value();
scrollBarValuesOnMousePress.ry() = verticalScrollBar()->value();
e->accept();
}
void SvgWindow::mouseMoveEvent(QMouseEvent *e)
{
horizontalScrollBar()->setValue(scrollBarValuesOnMousePress.x() - e->pos().x() +mousePressPos.x());
verticalScrollBar()->setValue(scrollBarValuesOnMousePress.y() - e->pos().y() +mousePressPos.y());
horizontalScrollBar()->update();
verticalScrollBar()->update();
e->accept();
}