《Qt6开发及实例》6-4 显示SVG格式图片

news2024/11/23 8:38:33

目录

一、简介与设计

1.1 简介

1.2 设计

二、SvgWidget

2.1 鼠标滚轮事件

三、svgwindow

四、MainWindow


 

一、简介与设计

1.1 简介

1、SVG 的英文全称是 Scalable Vector Graphics,即可缩放的矢量图形。它是由万维网联盟(W3C)在 2000 年 8 月制定的一种新的二维矢量图形格式

 

2、SVG 的特点如下:

(1) 基于XML

(2) 采用文本来描述对象

(3)  具有交互性和动态性

(4) 完全支持 DOM

 

3、SVG 中画折线的标签如下

<polyline fill="none" stroke="#888888" stroke-width="2" points="100, 200, 100, 100"/>

polyline:表示绘制折线

fill:表示填充

stroke:表示画笔颜色

stroke-width:表示画笔宽度

points:表示折线的点

 

4、SVG 是一种矢量图形格式,比 GIF、JPGE 等栅格格式具有众多优势,如文件小;可任意缩放而不会破坏图像的清晰度和细节;图像中的文字独立于图像,文字保留可编辑和可搜寻的状态

 

5、Qt 的 XML 模块支持两种 XML 解析方法:DOM 和 SAX。DOM 方法将 XML 文件表示为一棵树,可以随机访问其中的节点,内存消耗较大。SAX 是一种事件驱动的 XML API,其速度快,但不便于随机访问任意节点

 

6、Qt 为 SVG 格式图片的显示与生成提供了专门的 QtSvg 模块,此模块中包含了与 SVG 图片相关的所有类,主要有 QtSvgWidget、QSvgRender 和 QGraphicsSvgItem

 

1.2 设计

界面

通过 QtSvgWidget 类和 QSvgRender 类实现一个 SVG 图片浏览器,显示以 ".svg" 结尾的文件以介绍 SVG 格式图片显示的方法

0b644129823646dca53b691a84c57507.png

结构

847f22a1383d4a4a9f0c2370d73fe760.jpg

 

建立项目

项目名:SVGTest

40ec05314c304efa95fb77c07e3f7771.png

 a4c4cda80db9430ab9f9965bab3876a0.png

1498c2004c8f47e79d9340bd8a017cb7.png

90b966bea97e4adfa2ef3898181e6a52.png

 

二、SvgWidget

2.1 鼠标滚轮事件

aac823775d154976be21485f947ad1ba.png

svgwidget.h

#ifndef SVGWINDOW_H
#define SVGWINDOW_H

#include <QtSvg>
#include <QSvgWidget>
#include <QSvgRenderer>

class SvgWidget : public QSvgWidget
{
    Q_OBJECT
public:
    SvgWidget(QWidget *parent = 0);
    void wheelEvent(QWheelEvent *);  //相应鼠标的滚轮事件,使SVG图片能够通过鼠标滚轮的滚顶进行缩放

private:
    QSvgRenderer *render;            //用于图片显示尺寸的确定
};

#endif // SVGWINDOW_H

svgwidget.cpp

#include "svgwidget.h"

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

// 鼠标滚动事件
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->angleDelta().y() > 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) const double diff = 0.1; 

鼠标每滚动一次,图片大小改变的比例,这个可以写在配置文件里面

 

(b) QSize size = render->defaultSize();

这一句和后面两句用于获取图片尺寸

 

(c) if(e->angleDelta().y() > 0)

获取鼠标滚动的角度,e->angleDelta().y() > 0 表示鼠标向远离用户的方向滚动。滚轮每滚动 1° 相当于移动 8°,常见鼠标滚动一下的角度为 15°,所以滚动一下相当于移动了 120°(=15°*8)

 

三、svgwindow

0b2b3fb64b2647498c749d18e4dec084.png

 svgwindow.h

#ifndef SVGWINDOW_H
#define SVGWINDOW_H

#include <QScrollArea>
#include "svgwidget.h"

// SvgWindow继承自QScrollArea类,是一个带滚动条的显示区域。
// 它包含svgWidget类,当图片放大到超过主窗口大小时,能够通过滚
// 轮查看全貌
class SvgWindow : public QScrollArea
{
public:
    SvgWindow(QWidget *parent = 0);
    void setFile(QString);
    void mousePressEvent(QMouseEvent *);
    void mouseMoveEvent(QMouseEvent *);

private:
    SvgWidget *svgWidget;
    QPoint mousePressPos;
    QPoint scrollBarValueOnMousePress;
};


#endif // SVGWINDOW_H

svgwindow.cpp

#include "svgwindow.h"

SvgWindow::SvgWindow(QWidget *parent) : QScrollArea(parent)
{
    //调用QScrollArea类的setWidget()函数设置滚动区的窗体,
    //使svgWidget成为SvgWindow的子窗口
    svgWidget = new SvgWidget;
    setWidget(svgWidget);
}

void SvgWindow::setFile(QString fileName)
{
    //主窗口对文件进行选择或修改时,调用setFile()函数设置新的文件
    svgWidget->load(fileName);                     // 将新的SVG文件加载到svgWidget中进行展示
    QSvgRenderer *render = svgWidget->renderer();
    svgWidget->resize(render->defaultSize());      // 使svgWidget窗体按SVG图片的默认尺寸进行显示
}

// 分别获得svgWindow的水平滚动条和垂直滚动条
void SvgWindow::mousePressEvent(QMouseEvent *event)
{
    mousePressPos = event->pos();
    scrollBarValueOnMousePress.rx() = horizontalScrollBar()->value();
    scrollBarValueOnMousePress.ry() = verticalScrollBar()->value();
    event->accept();
}

//鼠标键被按下并拖拽鼠标时触发mouseMoveEvent()函数,
//通过滚动条的位置设置实现图片拖拽的效果:
void SvgWindow::mouseMoveEvent(QMouseEvent *event)
{
    //对水平滚动条的新位置进行设置
    horizontalScrollBar()->setValue(scrollBarValueOnMousePress.x() - event->pos().x() + mousePressPos.x());
    //对垂直滚动条的新位置进行设置
    horizontalScrollBar()->update();
    verticalScrollBar()->update();
    event->accept();
}

 

四、MainWindow

83bb3a25c89b4cc99e00c8681ed5f271.png

 mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "svgwindow.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void createMenu();

public slots:
    void slotOpenFile();

private:
    SvgWindow *svgWindow;  //用于调用相关函数传递选择的文件名
};
#endif // MAINWINDOW_H

mainwindow.cpp 

#include "mainwindow.h"

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

MainWindow::~MainWindow()
{
}

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

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



 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/360814.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是循环依赖,spring是如何去解决循环依赖问题的?什么是三级缓存?【spring】

文章目录什么是循环依赖&#xff1f;什么是三级缓存&#xff1f;执行流程什么是循环依赖&#xff1f; 在我们的开发中&#xff0c;会不可避免的遇到Bean之间循环依赖的&#xff0c;所谓循环依赖&#xff0c;就是两个或者两个以上的Bean互相持有对方&#xff0c;这样在程序运行…

几个流畅阅读与标记PDF文件的顶级 PDF 注释器

使用 PDF 注释工具改变您修改 PDF 文档的方式。 PDF 注释器提供了广泛的对象集&#xff0c;用于对内容进行说明。PDF 注释器的目的范围从标记页面内容到添加有洞察力的功能&#xff08;如表单&#xff09;。 您可以在评论表中添加建议&#xff0c;例如 – 便签。注释是指在 P…

【假捻停线需求沟通】

假捻工单上停产按钮: 假捻工单上结批复产按钮: 这是目前MES系统具备的功能,但是MES的生产状态和SAP不同步,也就是说MES的A机台上的B订单还在生产,SAP把B订单结批,但是当你刷新页面时,SAP会取A机台上的最新订单数据,也就是B订单进行显示。 换言之,SAP结批不掉A机台上…

PX4之代码结构

PX4开源飞控是目前主流的开源飞控项目&#xff0c;被很多公司作为飞控开发的参考。也广泛被用于现在流行的evtol验证机的飞控&#xff0c;进行初步的飞行验证。可能大多数AAM以及UAM都离不开PX4。 项目代码可以从github下载 $ git clone --recursive GitHub - PX4/PX4-Autopil…

构建Yocto项目

前言Yocto Project简称YP, 是一个致力于帮助开发者构建自己的Linux嵌入式的项目&#xff0c;除了Yocto还有其它的开源项目例如&#xff1a;Debian&#xff0c;著名的Ubuntu就是基于Debian来构建的发行版。什么是Yocto Project&#xff1f;Yocto Project (YP)是一个开源协作项目…

分类预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积门控循环单元数据分类预测

分类预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积门控循环单元数据分类预测 目录分类预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积门控循环单元数据分类预测分类效果基本描述模型描述程序设计参考资料分类效果 基本描述 1.Matlab实现WOA-CNN-GRU多特征分类预测&#xff0c;…

excel图表设计:有关表头的相关问题汇总

虽然表头很简单&#xff0c;但因为有不同样式需要、不同打印需要&#xff0c;也有很多人在表头上浪费了很多时间。文章总结了8种表头的典型形式和问题&#xff0c;让大家从此不再为表头浪费时间。每个excle表格都有一个表头&#xff0c;适合的表头能够让表格美观、逻辑清晰&…

2023年PMP考试内容有哪些?怎么备考?

PMP考试也叫项目管理专业人士资格认证&#xff0c;要想参加2023年PMP考试&#xff0c;考生还需先对PMP考试内容提前进行了解&#xff0c;那么2023年PMP考试内容有哪些呢&#xff1f;我们先看下官方公告&#xff1a;大白话说就是虽然2023年PMBOK第七版就要在大陆地区正式投入使用…

Android项目如何将同一套代码应用于多个项目(变种打包)

如果你的公司开发了一个项目&#xff0c;但是这个项目应用于不同的客户&#xff0c;根据客户的不同要求&#xff0c;会改动一些东西&#xff0c;之前我们的做法是直接将这套代码复制出来&#xff0c;替换logo,applicationId,以及一些基本配置&#xff08;如baseurl,等配置&…

vue3.2中使用swiper缩略图轮播教程

介绍 在vue3 中使用 swiper 实现缩略图的轮播图效果,具体如下图所示: 使用 切换到项目终端 ,输入命令 npm install swiper --save , 进行安装在 main.js里,引入 swiper.css并使用,具体代码如下;import {createApp } from vue import App from ./App.vue import router…

微信公众号抽奖怎么做_分享微信抽奖小程序制作的好处

在H5游戏中&#xff0c;抽奖是最受消费者喜爱的模式之一。将H5微信抽奖活动结合到营销中&#xff0c;可以带来意想不到的效果&#xff0c;带流量和曝光率&#xff0c;所以许多企业也会在做活动时添加上不同类型的H5微信抽奖活动。编辑那么&#xff0c;新手怎么搭建微信抽奖活动…

前端二面react面试题集锦

react diff 算法 我们知道React会维护两个虚拟DOM&#xff0c;那么是如何来比较&#xff0c;如何来判断&#xff0c;做出最优的解呢&#xff1f;这就用到了diff算法 diff算法的作用 计算出Virtual DOM中真正变化的部分&#xff0c;并只针对该部分进行原生DOM操作&#xff0c;而…

学成在线项目笔记

业务层开发 DAO开发示例 生成实体类对应的mapper和xml文件 定义MybatisPlusConfig&#xff0c;用于扫描mapper和配置分页拦截器 MapperScan("com.xuecheng.content.mapper") Configuration public class MybatisPlusConfig {Beanpublic MybatisPlusInterceptor myb…

Datawhale团队第九期录取名单!

Datawhale团队 公示&#xff1a;Datawhale团队成员Datawhale成立四年了&#xff0c;从一开始的12个人&#xff0c;学习互助&#xff0c;到提议成立开源组织&#xff0c;做更多开源的事情&#xff0c;帮助更多学习者&#xff0c;也促使我们更好地成长。于是有了我们的使命&#…

【Spring Boot 原理分析】- 自动配置

【Spring Boot 原理分析】- 自动配置 Condition 注解 Condition 是 Spring 4.0 增加的条件判断功能&#xff0c;通过这个功能可以实现选择的创建 Bean 操作 &#x1f451; 我们在使用 Spring 的时候&#xff0c;只需导入某个依赖的坐标&#xff0c;就可以直接通过 Autwired 注…

零基础小白如何学会数据分析?

随着数字经济、大数据时代的发展&#xff0c;数据已然成为当下时代最重要的盈利资源&#xff0c;让企业在做决策和计划方案时更有针对性和依据&#xff0c;能提前预测市场发展方向&#xff0c;做好布局。由此而产生的数据分析岗位也逐渐被更多企业重视&#xff0c;特别是中大型…

社招中级前端笔试面试题总结

HTTP世界全览 互联网上绝大部分资源都使用 HTTP 协议传输&#xff1b;浏览器是 HTTP 协议里的请求方&#xff0c;即 User Agent&#xff1b;服务器是 HTTP 协议里的应答方&#xff0c;常用的有 Apache 和 Nginx&#xff1b;CDN 位于浏览器和服务器之间&#xff0c;主要起到缓存…

Notion AI是什么?和chatgpt比哪个好?

最近对于人工智能的热度可谓是前所未有的高涨&#xff0c;毕竟现在的人工智能发展是越来越快&#xff0c;能做的事情也是越来越多&#xff0c;不再是那种低等的假智能小爱同学和siri那种。今天我们主要来聊聊Notion AI和chatgpt吧&#xff0c;Notion AI是什么&#xff1f;和cha…

leaflet 删除所有的marker图层,保留其他图层(085)

第085个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet项目中清除所有的marker图层,保留其他图层,详情请参考源代码。这里面主要用到了(layer instanceof L.Marker ,注意 L.Marker中Marker首字母要大写。 直接复制下面的 vue+leaflet源代码,操作2分钟即可运行…

【5000左右电脑配置清单】预算不高于5000,不带显示器的电脑配置清单推荐

由于本人是学生党经济有限&#xff0c;预算不高于5000元配一套电脑主机&#xff0c;说实话5000左右的电脑配置已经很好了&#xff0c;今天站长整理了几款配置给大家参考参考&#xff0c;更多电脑配置还请继续关注西安SEO优化站点&#xff01; 配置1&#xff1a; <CPU> I5…