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

来源:互联网 发布:mac虚拟机安装win10 编辑:程序博客网 时间:2024/05/18 01:14

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_OBJECTpublic:    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_OBJECTpublic:    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_OBJECTpublic:    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_OBJECTpublic:    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:表示折线的点
原创粉丝点击