Qt5开发学习之图形与SVG图像(八)

Qt5开发学习之图形与SVG图像(八)

2017-08-21 20:34:39 沾糖的柿子 阅读数 3954更多

分类专栏: 技术文档

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/m0_37897437/article/details/77458399

Qt5位置相关函数

Qt提供了很多关于获取窗体位置及显示区域大小的函数,统称为“位置函数”或“位置相关函数”。

x()、y()、pos():

作用数获得整个窗体左上角的坐标位置。

frameGeometry()和geometry():

这两个函数相对应,frameGeometry()获取的是整个窗体的左上角顶点和长宽值,而geometry()获取的是窗体内中心区域的左上角顶点坐标及长宽值。

width()、height():

获得中心区域的长宽值。

rect()、size():

size()获得中心区域的长宽值,rect()和geometry()相同,返回的是一个QRect对象,但是获得的左上角顶点坐标永远是(0, 0)。

实例试验各个位置函数效果: 
geometry.h:

 #include <QDialog>
#include <QLabel>
#include <QGridLayout>

class Geomtry : public QDialog
{
    Q_OBJECT

public:
    Geomtry(QWidget *parent = 0);
    ~Geomtry();

    void updateLabel();

private:
    QLabel *xLabel;
    QLabel *xValueLabel;
    QLabel *yLabel;
    QLabel *yValueLabel;
    QLabel *frmLabel;
    QLabel *frmValueLabel;
    QLabel *posLabel;
    QLabel *posValueLabel;
    QLabel *geoLabel;
    QLabel *geoValueLabel;
    QLabel *widthLabel;
    QLabel *widthValueLabel;
    QLabel *heightLabel;
    QLabel *heightValudeLabel;
    QLabel *rectLabel;
    QLabel *rectValueLabel;
    QLabel *sizeLabel;
    QLabel *sizeValudeLabel;

    QGridLayout *mainLayout;

protected:
    void moveEvent(QMoveEvent *);
    void resizeEvent(QResizeEvent *);
};

geometry.cpp:

#include "geomtry.h"

Geomtry::Geomtry(QWidget *parent)
    : QDialog(parent)
{
    xLabel = new QLabel(tr("x():"));
    xValueLabel = new QLabel;
    yLabel = new QLabel(tr("y():"));
    yValueLabel = new QLabel;
    frmLabel = new QLabel(tr("y():"));
    frmValueLabel = new QLabel;
    posLabel = new QLabel(tr("pos():"));
    posValueLabel = new QLabel;
    geoLabel = new QLabel(tr("geomtry():"));
    geoValueLabel = new QLabel;
    widthLabel = new QLabel(tr("width():"));
    widthValueLabel = new QLabel;
    heightLabel = new QLabel(tr("height():"));
    heightValudeLabel = new QLabel;
    rectLabel = new QLabel(tr("rect():"));
    rectValueLabel = new QLabel;
    sizeLabel = new QLabel(tr("size():"));
    sizeValudeLabel = new QLabel;

    mainLayout = new QGridLayout(this);
    mainLayout->addWidget(xLabel, 0, 0);
    mainLayout->addWidget(xValueLabel, 0, 1);
    mainLayout->addWidget(yLabel, 1, 0);
    mainLayout->addWidget(yValueLabel, 1, 1);
    mainLayout->addWidget(frmLabel, 2, 0);
    mainLayout->addWidget(frmValueLabel, 2, 1);
    mainLayout->addWidget(posLabel, 3, 0);
    mainLayout->addWidget(posValueLabel, 3, 1);
    mainLayout->addWidget(geoLabel, 4, 0);
    mainLayout->addWidget(geoValueLabel, 4, 1);
    mainLayout->addWidget(widthLabel, 5, 0);
    mainLayout->addWidget(widthValueLabel, 5, 1);
    mainLayout->addWidget(heightLabel, 6, 0);
    mainLayout->addWidget(heightValudeLabel, 6, 1);
    mainLayout->addWidget(rectLabel, 7, 0);
    mainLayout->addWidget(rectValueLabel, 7, 1);
    mainLayout->addWidget(sizeLabel, 8, 0);
    mainLayout->addWidget(sizeValudeLabel, 8, 1);

    updateLabel();
}

Geomtry::~Geomtry()
{

}

// 实现实时更新位置数据
void Geomtry::updateLabel()
{
    QString xStr;
    xValueLabel->setText(xStr.setNum(x()));

    QString yStr;
    yValueLabel->setText(yStr.setNum(y()));

    // 获得frameGeometry()函数的结果并显示
    QString frameStr;
    QString frameStr1, frameStr2, frameStr3, frameStr4;
    frameStr = frameStr1.setNum(frameGeometry().x()) + "," +
                frameStr2.setNum(frameGeometry().y()) + "," +
                frameStr3.setNum(frameGeometry().width()) + "," +
                frameStr4.setNum(frameGeometry().height());

    frmValueLabel->setText(frameStr);

    QString posStr;
    QString posStr1, posStr2;
    posStr = posStr1.setNum(pos().x()) + posStr2.setNum(pos().y());
    posValueLabel->setText(posStr);

    QString geoStr;
    QString geoStr1, geoStr2, geoStr3, geoStr4;
    geoStr = geoStr1.setNum(geometry().x()) + "," +
             geoStr2.setNum(geometry().y()) + "," +
             geoStr3.setNum(geometry().width()) + "," +
             geoStr4.setNum(geometry().height());
    geoValueLabel->setText(geoStr);

    QString wStr, hStr;
    widthValueLabel->setText(wStr.setNum(width()));
    heightValudeLabel->setText(hStr.setNum(height()));

    QString rectStr;
    QString rectStr1, rectStr2, rectStr3, rectStr4;
    rectStr = rectStr1.setNum(rect().x()) + "," +
              rectStr2.setNum(rect().y()) + "," +
              rectStr3.setNum(rect().width()) + "," +
              rectStr4.setNum(rect().height());
    rectValueLabel->setText(rectStr);

    QString sizeStr;
    QString sizeStr1, sizeStr2;
    sizeStr = sizeStr1.setNum(size().width()) + "," + sizeStr2.setNum(size().height());
    sizeValudeLabel->setText(sizeStr);
}

// 重定义QWidget的moveEvent函数,响应对话框移动事件
void Geomtry::moveEvent(QMoveEvent *)
{
    updateLabel();
}

// 重定义QWidget的resizeEvent函数,响应对话框大小调整事件
void Geomtry::resizeEvent(QResizeEvent *)
{
    updateLabel();
}

实现如图: 
这里写图片描述


Qt5显示SVG格式图片

SVG的英文全称是Scalabe Vector Graphics,即可缩放的矢量图形。它是由万维网联盟制定的一种新的二维矢量图形格式,是一个开放的图形标准。

SVG格式有以下特点:

1、基于XML;

2、采用文本来描述对象;

3、具有交互性和动态性; 
4、完全支持DOM;

SVG格式相对于GIF、JPEG格式的优势是:SVG是一种矢量图形格式,相比较来说文件较小,网络传输速度快;可任意缩放而不会破坏图像的清晰度和细节;图像中的文字独立于图像,文字保留可编辑和可搜寻状态,也没有字体的限制。

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

使用SVG模块,要在工程文件.pro中加入一行代码:Qt += svg,然后在头文件中包含相应的库:#include <QtSvg>

实例使用Qt的SVG模块实现一个现实SVG功能的窗口,可以对SVG模块进行放大与缩小。 
首先在项目中添加一个类用于显示SVG图片,类名为:SvgWidget

// svgwidget主要用于显示SVG图片
#include <QSvgWidget>
#include <QtSvg>
#include <QSvgRenderer>
#include <QWheelEvent>

class SvgWidget : public QSvgWidget
{
    Q_OBJECT
public:
    SvgWidget(QWidget *parent = 0);

    // 响应鼠标滚轮事件,使SVG图片能够通过鼠标滚轮的滚动改变图片大小
    void wheelEvent(QWheelEvent *);

private:
    // 用于图片显示尺寸的确定
    QSvgRenderer *render;
};
SvgWidget::SvgWidget(QWidget *parent) : QSvgWidget(parent)
{
    // 构造函数获得本窗体的QSvgRenderer对象
    render = renderer();
}

void SvgWidget::wheelEvent(QWheelEvent *event)
{
    // 定义一个值,表示每次滚轮滚动的值,图片大小改变的比例
    const double diff = 0.1;
    // 先获取图片显示区的大小,以便进行下一步操作
    QSize size = render->defaultSize();
    int width = size.width();
    int height = size.height();

    // delta()函数获得滚轮滚动的距离值,返回值大于零是向前滚动
    if (event->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用于放置变换大小的图片:


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

// QScrollArea 是一个滚动区域,当图片放大超过主窗口的尺寸时,通过拖曳滚动条方式进行查看
class SvgWindow : public QScrollArea
{
    Q_OBJECT
public:
    SvgWindow(QWidget *parent = 0);
    void setFile(QString);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);

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

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

// 当主窗口中对文件进行了选择和修改时,将调用setFile()函数设置新的文件
void SvgWindow::setFile(QString fileName)
{
    if (fileName == "")
        return;

    svgWidget->load(fileName);
    QSvgRenderer *render = svgWidget->renderer();
    svgWidget->resize(render->defaultSize());
}

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

void SvgWindow::mouseMoveEvent(QMouseEvent *event)
{
    horizontalScrollBar()->setValue(scrollBarValueOnMousePress.x() - event->pos().x() + mousePressPos.x());
    verticalScrollBar()->setValue(scrollBarValueOnMousePress.y() - event->pos().y() + mousePressPos.y());
    horizontalScrollBar()->update();
    verticalScrollBar()->update();
    event->accept();
}

最后创建一个主窗口界面用于打开SVG图片选项MainWindow

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

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void createMenu();
private slots:
    void slotOpenFile();
private:
    SvgWindow *svgWindow;
};
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->resize(600, 600);
    setWindowTitle(tr("SvgWindow"));
    createMenu();

    svgWindow = new SvgWindow;
    setCentralWidget(svgWindow);
}

MainWindow::~MainWindow()
{

}

void MainWindow::createMenu()
{
    QMenu *fileMenu = menuBar()->addMenu(tr("File"));
    QAction *openAction = new QAction(tr("open"), this);

    connect(openAction, &QAction::triggered, this, &MainWindow::slotOpenFile);
    fileMenu->addAction(openAction);
}

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

完成后实例效果如下: 
Qt_SVG


Qt格式SVG格式图片的显示方法:概念解析

Qt的XML模块支持两种XML解析方法,DOM和SAX。

  • DOM方法将XML解析成一棵数,以便随机访问其中的节点,但是消耗内存相对多一些。
  • SAX是一种事件驱动的XML API,速度快,但不支持随机访问。

这里介绍一下DOM的使用方法: 
文档对象模型(Document Object Model DOM)能够使程序和脚本动态的存取和更新XML文档的内容、结构和风格。 
DOM将XML表示成一颗数,用户通过API可以随意地访问输的任意节点的内容。在Qt中,XML文档自身用QDomDocument表示。所有的节点都从QDomNode继承。

SVG是利用XML表示的矢量图形文件,每种图形都用XML标签表示。例如:
<polyline fill="none" stroke="#888888" stroke-width="2" points="100,200,100,100"/>
  • polyline:表示绘制折线
  • fill:属性表示填充
  • stroke:表示画笔颜色
  • stroke-width:表示画笔宽度
  • points:表示折线的点
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: SVG编译器是一种可以将SVG图形文件转换成矢量图形的工具,它可以帮助用户快速地定制设计向量图形。而C和Qt作为编程语言和图形界面工具,可以用来实现SVG编译器的图形基类。 在C语言中,可以使用OpenGL库来实现图形基类。OpenGL是一种跨平台的图形库,可以用来绘制2D和3D图形。C语言中可以使用OpenGL库的接口函数来实现SVG编译器的图形基类。 在Qt图形框架中,可以使用QWidget类或QGraphicsItem类来实现图形基类。QWidget类是Qt中的基本窗口组件,它可以用来绘制2D图形,并可以添加自定义控件。而QGraphicsItem类是用于创建图形项的基类,它可以用来表示各种形状的图像,并可以添加动画效果和交互功能。 无论是C还是Qt,都可以基于图形库和图形框架来实现SVG编译器的图形基类。通过编写对应的代码,将SVG文件转换成矢量图形,可以帮助用户实现定制设计。同时,在用户使用SVG编译器时,更加友好的交互界面和多种样式的SVG图形设计,可以更好地提高软件的效率和用户的使用体验。 ### 回答2: SVG编译器是一种可以将SVG(可缩放矢量图形)文件转换为其他格式的软件,现在许多应用程序都需要这种功能。C和Qt是编写SVG编译器所需的两个主要技术。 C是一种通用的高级编程语言,其代码执行效率高,所以它在整个计算机科学领域得到广泛应用。编写SVG编译器时,使用C语言可以提高性能,使得程序更快地运行。在使用C语言时,需要使用C标准库、C编译器和管道、文件操作等技术来创建SVG编译器。 Qt是一个用于构建图形界面和应用程序的跨平台应用程序框架,可用于创建Mac、Windows和Linux等操作系统上的GUI应用程序。在编写SVG编译器时,使用Qt可以使程序看起来很专业且易于使用,具有很好的用户体验。Qt拥有丰富的内置工具包,包括控件、图形、网络通信等库,开发者可以根据自己的需要选择使用。你可以编写一个基于Qt图形基类,实现SVG编译器的第一层UI。 SVG编译器的图形基类是使应用程序看起来简洁且易于使用的重要部分。通过创建和设计具有良好布局和优秀操作的图形基类,可以增强应用程序的用户体验。实现SVG编译器图形基类时,需要考虑窗口大小、按钮位置、文本框位置、滑块大小等,以便用户可以方便地使用它。 综合来看,使用C和Qt的组合可以有效地实现SVG编译器的图形基类,并推进SVG编译器的发展,更好地满足用户的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值