利用SVG在QML中画图

在我先前的文章"在QML应用中使用Canvas来画图"中,我展示如何利用QML中的Canvas来画我们的曲线.今天在我们的文章中,我们来展示如何利用SVG在我们的例程中画我们所需要的曲线.


我们可以直接使用一个已经存在的SVG画画库simple-svg.它的源码位于"https://code.google.com/archive/p/simple-svg/downloads".对于一下开发者来说可能需要VPN才可以下载哦.


我们可以利用我们的SDK中提供的一个标准的"QML App with C++ plugin (qmake)"来创建一个简单的模版.同时,我们修改我们的plugin的代码如下:

mytype.h


#ifndef MYTYPE_H
#define MYTYPE_H

#include <QObject>

class MyType : public QObject
{
    Q_OBJECT
    Q_PROPERTY( QString helloWorld READ helloWorld WRITE setHelloWorld NOTIFY helloWorldChanged )

public:
    explicit MyType(QObject *parent = 0);
    ~MyType();
    Q_INVOKABLE void draw(const int &width, const int &height, const QString &array);

Q_SIGNALS:
    void helloWorldChanged();

protected:
    QString helloWorld() { return m_message; }
    void setHelloWorld(QString msg) { m_message = msg; Q_EMIT helloWorldChanged(); }

    QString m_message;
};

#endif // MYTYPE_H

在上面我们添加了一个叫做"draw"的方法.它的定义如下:

mytype.cpp


#include "mytype.h"
#include "simple_svg.h"

using namespace svg;

MyType::MyType(QObject *parent) :
    QObject(parent),
    m_message("")
{

}

MyType::~MyType() {

}

void MyType::draw(const int &width, const int &height, const QString &array)
{
    // Create the SVG doc
    Dimensions dimensions(width, height);
    Document doc("../svggraph/svggraph/graph.svg", Layout(dimensions, Layout::BottomLeft));

    // Parse our string into an array
    std::istringstream buf(array.toStdString());
    std::istream_iterator<std::string> beg(buf), end;
    std::vector<std::string> tokens(beg, end);

    // Create a line
    Polyline polyline_a(Stroke(1.5, Color::Cyan));

    // Iterate over our array to define line start/end points
    for( int a = 0; a < tokens.size(); a = a + 1 )
    {
        if (tokens.size() < 2) {
            polyline_a << Point(width/(tokens.size())*(a), atoi(tokens[a].c_str())) << Point(width/(tokens.size())*(a+1), atoi(tokens[a].c_str()));
        } else {
            polyline_a << Point(width/(tokens.size()-1)*(a), atoi(tokens[a].c_str()));
        }
    }
    doc << polyline_a;

    // Save the doc
    doc.save();
}

在这里,我们把从地址 https://code.google.com/archive/p/simple-svg/downloads下载的文件重新命令为"simple_svg.h",并把它存于位于plugins所在目录的根目录中,也即:

svggraph/backend/Svggraph

我们可以重新编译我们的应用.

在我们的Main.qml中,我们可以利用我们刚刚创建的plugin来画我们的UI.和先前不同的是,这里,我们使用一个叫做Image的而不是一个Canvas.

Main.qml

import QtQuick 2.4
import Ubuntu.Components 1.3
import Svggraph 1.0
/*!
    \brief MainView with a Label and Button elements.
*/

MainView {
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "svggraph.liu-xiao-guo"

    width: units.gu(60)
    height: units.gu(85)

    MyType {
        id: myType
    }

    Page {
        id: page
        header: PageHeader {
            id: pageHeader
            title: i18n.tr("svggraph")
            StyleHints {
                foregroundColor: UbuntuColors.orange
                backgroundColor: UbuntuColors.porcelain
                dividerColor: UbuntuColors.slate
            }
        }

        Rectangle {
            anchors {
                top:page.header.bottom
                left: page.header.left
                right: page.header.right
            }
            height: parent.height - page.header.height

            TextField{
                id:txt
                width:parent.width - units.gu(4)
                anchors.top:parent.top
                anchors.horizontalCenter:parent.horizontalCenter
                anchors.margins:units.gu(2)
                text: "0 10 50 80 60 90"
            }
            Row {
                anchors.top:txt.bottom
                anchors.horizontalCenter: parent.horizontalCenter
                anchors.margins: units.gu(2)
                spacing: units.gu(2)
                Button {
                    id:drawButton
                    anchors.margins:units.gu(2)
                    text:i18n.tr("Draw")
                    enabled:(txt.length)
                    color: UbuntuColors.orange
                    onClicked: {
                        myType.draw(page.width, page.height, txt.text)
                        img.source = ""
                        img.source = Qt.resolvedUrl("graph.svg")
                    }
                }
                Button {
                    id:clearButton
                    anchors.margins:units.gu(2)
                    text:i18n.tr("Clear")
                    onClicked: {
                        myType.draw(page.width, page.height, "")
                        img.source = ""
                        img.source = Qt.resolvedUrl("graph.svg")
                    }
                }
            }
            Image {
                id:img
                anchors.fill:parent
                anchors.margins:units.gu(2)
                cache:false
                source: Qt.resolvedUrl("graph.svg")
            }
        }
    }
}

在这里,我们通过按钮"Draw"把我们所需要的数据传入到plugin中,并生产graph.svg文件,并在UI的Image中得以显示:






整个项目的源码在: https://github.com/liu-xiao-guo/svggraph
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值