2

I have a Simple QML project working with SVG files.

here i can load image.svg from qrc resource properly.

Image {
        id: svg
        source: "svg/image.svg"
        x: 0
        y: header.height
        fillMode: Image.PreserveAspectFit
    }

I want to know is that possible to assign a DOM SVG as String to Image.source ?

the String like this:

<svg version="1.1" id="svg2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1147.592px" height="1397.27px" viewBox="0 0 1147.592 1397.27" enable-background="new 0 0 1147.592 1397.27" xml:space="preserve"><polygon fill="none" stroke="#010101" stroke-miterlimit="10" points="839.432,179.454 839.432,190.151 
852.657,189.897 852.657,180.621 "/></svg>
hamed
  • 63
  • 1
  • 6

2 Answers2

7

You can embed image data using data URI exactly as it could be done in HTML:

import QtQuick 2.11
import QtQuick.Window 2.2

Window {
    visible: true
    width: 200
    height: 200
    title: qsTr("Inline SVG example")

    Image {
        anchors.centerIn: parent
        source: "data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 105\"> <g fill=\"#97C024\" stroke=\"#97C024\" stroke-linejoin=\"round\" stroke-linecap=\"round\"> <path d=\"M14,40v24M81,40v24M38,68v24M57,68v24M28,42v31h39v-31z\" stroke-width=\"12\"/> <path d=\"M32,5l5,10M64,5l-6,10 \" stroke-width=\"2\"/> </g> <path d=\"M22,35h51v10h-51zM22,33c0-31,51-31,51,0\" fill=\"#97C024\"/> <g fill=\"#FFF\"> <circle cx=\"36\" cy=\"22\" r=\"2\"/> <circle cx=\"59\" cy=\"22\" r=\"2\"/> </g> </svg>"
    }
}

The image source could be encoded using Base64 for convenience. But I don't think it's effective way to draw SVG. You should either load SVG file or draw SVG image directly using Qt SVG.

folibis
  • 12,048
  • 6
  • 54
  • 97
  • It would be worth mentioning why you don't think it's effective. – Mitch Jun 27 '18 at 12:35
  • @Mitch, I meant that even without taking into account excessive size of the string (in Base64 case it will be even more) the path is: encoding->parsing->drawing. I just suggest drawing directly, using Qt SVG API. – folibis Jun 27 '18 at 12:45
  • Oh right, you meant using Base64 specifically would not be efficient. I still think it's worth adding that to the answer itself though. :) – Mitch Jun 27 '18 at 12:50
0

This is similar to @folibis answer, but, I want to highlight the following enhancements:

  • ES6 backtick notation allows us to drop a multiline SVG into our source code
  • In the original question, the supplied viewBox makes the SVG tiny, so, I removed the viewBox
  • Definitely use "data-URI" but, because it's SVG there's no need to use base64 encoding/decoding, plain text is sufficient
  • I generally use icon.source and icon.color to recolor an SVG
  • See my AppIcon where I reuse the icon property from a Button to render an SVG
import QtQuick
import QtQuick.Controls

Page {
    property string dataUri: `data:image/svg+xml;utf8,
<svg xmlns="http://www.w3.org/2000/svg">
<polygon fill="none" stroke="#010101" stroke-miterlimit="10" points="839.432,179.454 839.432,190.151 
852.657,189.897 852.657,180.621 "/>
</svg>`

    Image {
        x: 32
        y: 32
        width: 64
        height: 64
        source: dataUri
        sourceSize: Qt.size(width, height)
    }

    AppIcon {
        x: 128
        y: 32
        width: 64
        height: 64
        icon.source: dataUri
        icon.color: pressed ? "orange" : "red"
    }
}

//AppIcon.qml
import QtQuick
import QtQuick.Controls
Item {
    id: appIcon
    property alias icon: btn.icon
    implicitWidth: 32
    implicitHeight: 32
    property alias pressed: btn.pressed
    signal clicked()
    Button {
        id: btn
        anchors.centerIn: parent
        background: Item { }
        icon.source: dataUri
        icon.width: parent.width
        icon.height: parent.height
        onClicked: appIcon.clicked()
    }
}

You can Try it Online!

Stephen Quan
  • 21,481
  • 4
  • 88
  • 75