需要在QML中更改SVG图像的颜色

时间:2022-06-28 20:31:18

I'm trying to design a synoptic panel in Qt-QML (for desktop). The interface should be used with fixed resolution, so I prefer to use PNG images for different graphical elements to create schema (pipe, pipe-curve, pipe-t, pump, valve, etc.). Now the problem is how to change fill color of different components: I'd like that user can choise the color (in real case scenario there are different liquid that can be used), but I cannot find how do that in QML. I thinked to use my PNG components as background, and then drawing a Rectangle over, masked by a SVG mask.. But on the web I can find only qt-components "MaskedItem" not available for desktop. I'm wondering if there's no way to put over my PNG an SVG image with one color (black and transparent), and then change color's property of this in QML. Anybody have got any ideas? Thanks really much.

我正在尝试设计一个Qt-QML的天气面板(用于桌面)。界面应该使用固定分辨率,所以我更喜欢使用不同图形元素的PNG图像来创建模式(管道、管道曲线、管道t、泵、阀门等)。现在的问题是如何更改不同组件的填充颜色:我希望用户可以选择颜色(在实际情况中,可以使用不同的液体),但是我无法在QML中找到如何做到这一点。我想用我的PNG组件作为背景,然后用SVG蒙版在上面画一个矩形。但是在web上,我只能找到不能用于桌面的qt组件“MaskedItem”。我想知道是否没有办法用一种颜色(黑色和透明)覆盖我的PNG SVG图像,然后在QML中更改它的颜色属性。有人有什么想法吗?真的很感谢。

(EDIT better explain)

(编辑更好的解释)

The problem is more complicated than I can be able to explain. I have created several QML components with specific properties, each component has a background image (PNG) with transparency. Now, what I need is fill a defined area of PNG image using a variable color "x", when the main QML is in a particular state (setted by Qt application). My problem was: how to fill the area of a PNG/SVG with a variable color, from QML? What I need is placing my "background" image, then apply over this a "Rectangle" component (color "x"), and finally put a mask on this Rectangle, to define what area of this must be visible, preserving the background (the bottom image of before). I hope I explained myself better now.

这个问题比我能解释的要复杂得多。我创建了几个具有特定属性的QML组件,每个组件都有一个透明的背景图像(PNG)。现在,我需要使用可变颜色“x”填充PNG图像的定义区域,此时主QML处于特定状态(由Qt应用程序设置)。我的问题是:如何从QML中使用可变颜色填充PNG/SVG区域?我需要的是放置我的“背景”图像,然后在这个矩形上应用一个“矩形”组件(颜色“x”),最后在这个矩形上放置一个蒙版,以定义这个矩形的哪个区域必须是可见的,保留背景(之前的底部图像)。我希望我现在能更好地解释我自己。

(EDIT solution) After a lot of hours, I was not able to find any other solutions than using qt-components MaskedItem. Below i have posted solution I used. Thank to you all for interest.

(编辑解决方案)很多小时后,除了使用qt组件MaskedItem之外,我找不到任何其他解决方案。下面是我使用的解决方案。谢谢大家的关心。

2 个解决方案

#1


3  

The only solution found is to use "qt-components MaskedItem"; it must be taken from repository and it must compile under Qt desktop. Now is possible to use MaskedItem in any QML component of synoptic. The QML code of components will be something like this:

找到的唯一解决方案是使用“qt-components MaskedItem”;它必须从存储库中取出,并且必须在Qt桌面下编译。现在可以在天气预报的任何QML组件中使用MaskedItem。组件的QML代码如下:

Item
{
    id: arrow
    property int  rotate: 0
    property bool active: false
    width: 32
    height: 32
    clip: true

    Image {
        smooth: true
        source: {
            if(rotate==90)
                "../res/arrow_1_bg.png"
            else if(rotate==180)
                "../res/arrow_2_bg.png"
            else if(rotate==270)
                "../res/arrow_3_bg.png"
            else
                "../res/arrow_0_bg.png"
        }
    }

    MaskedItem
    {
        visible: active
        anchors.fill: parent
        mask: Image
        {
            anchors.fill: parent
            smooth: true
            source: {
                if(rotate==90)
                    "../res/arrow_1_mask.png"
                else if(rotate==180)
                    "../res/arrow_2_mask.png"
                else if(rotate==270)
                    "../res/arrow_3_mask.png"
                else
                    "../res/arrow_0_mask.png"
            }
        }
        Rectangle
        {
            anchors.fill: parent
            color: active_color
            opacity: .6
        }
    }

} // Item: arrow

'active' property means if component must be "filled" or not, using global property "active_color" defined in the main QML.

“active”属性表示如果组件必须“填充”或不填充,则使用主QML中定义的全局属性“active_color”。

So, all components (pipes, pipes angle, arrows, pumps, valves, etc.) have got a background image (PNG) with transparency. Pipes (that have the "orientation" property, horizontal or vertical) are PNG 1x32px streched. An example of final screen can be something like this:

因此,所有组件(管道、管道角度、箭头、泵、阀门等)都有一个透明的背景图像(PNG)。管道(具有“方向”属性,水平或垂直)是PNG 1x32px。最终屏幕的例子可以是这样的:

example1 http://imageshack.us/a/img9/2968/example1c.png.

例二:http://imageshack.us/a/img9/2968/example1c.png。

All the components have also a MaskedItem, the mask image is used for define the visible area of a Rectangle (with color "x"), place over the main component's background image. An example of 2 components background and mask images:

所有组件都有一个MaskedItem,蒙版图像用于定义矩形的可见区域(颜色为“x”),放置在主组件的背景图像上。背景和蒙版图像两部分的一个例子:

example3 http://imageshack.us/a/img442/9863/example3y.png.

青年们http://imageshack.us/a/img442/9863/example3y.png。

The final result, if the 'active' property is true and the chosen color is green, can be something like this:

如果“活动”属性为真,选择的颜色为绿色,最后的结果可能是这样的:

example2 http://imageshack.us/a/img836/1968/example2c.png.

example2 http://imageshack.us/a/img836/1968/example2c.png。

#2


0  

Both PNG and SVG images support alpha channel (i.e. transparency), so, why don't you just put your SVG (with transparent parts where you wanto to see your background) over your PNG background?

PNG和SVG图像都支持alpha通道(即透明度),因此,为什么不将SVG(在希望看到背景的透明部分)放在PNG背景上呢?

Or even the other way around... you could put you PNG parts (with transparent "holes") over your SVG image.

或者反过来……您可以将PNG部件(带有透明的“孔”)放在SVG图像上。

#1


3  

The only solution found is to use "qt-components MaskedItem"; it must be taken from repository and it must compile under Qt desktop. Now is possible to use MaskedItem in any QML component of synoptic. The QML code of components will be something like this:

找到的唯一解决方案是使用“qt-components MaskedItem”;它必须从存储库中取出,并且必须在Qt桌面下编译。现在可以在天气预报的任何QML组件中使用MaskedItem。组件的QML代码如下:

Item
{
    id: arrow
    property int  rotate: 0
    property bool active: false
    width: 32
    height: 32
    clip: true

    Image {
        smooth: true
        source: {
            if(rotate==90)
                "../res/arrow_1_bg.png"
            else if(rotate==180)
                "../res/arrow_2_bg.png"
            else if(rotate==270)
                "../res/arrow_3_bg.png"
            else
                "../res/arrow_0_bg.png"
        }
    }

    MaskedItem
    {
        visible: active
        anchors.fill: parent
        mask: Image
        {
            anchors.fill: parent
            smooth: true
            source: {
                if(rotate==90)
                    "../res/arrow_1_mask.png"
                else if(rotate==180)
                    "../res/arrow_2_mask.png"
                else if(rotate==270)
                    "../res/arrow_3_mask.png"
                else
                    "../res/arrow_0_mask.png"
            }
        }
        Rectangle
        {
            anchors.fill: parent
            color: active_color
            opacity: .6
        }
    }

} // Item: arrow

'active' property means if component must be "filled" or not, using global property "active_color" defined in the main QML.

“active”属性表示如果组件必须“填充”或不填充,则使用主QML中定义的全局属性“active_color”。

So, all components (pipes, pipes angle, arrows, pumps, valves, etc.) have got a background image (PNG) with transparency. Pipes (that have the "orientation" property, horizontal or vertical) are PNG 1x32px streched. An example of final screen can be something like this:

因此,所有组件(管道、管道角度、箭头、泵、阀门等)都有一个透明的背景图像(PNG)。管道(具有“方向”属性,水平或垂直)是PNG 1x32px。最终屏幕的例子可以是这样的:

example1 http://imageshack.us/a/img9/2968/example1c.png.

例二:http://imageshack.us/a/img9/2968/example1c.png。

All the components have also a MaskedItem, the mask image is used for define the visible area of a Rectangle (with color "x"), place over the main component's background image. An example of 2 components background and mask images:

所有组件都有一个MaskedItem,蒙版图像用于定义矩形的可见区域(颜色为“x”),放置在主组件的背景图像上。背景和蒙版图像两部分的一个例子:

example3 http://imageshack.us/a/img442/9863/example3y.png.

青年们http://imageshack.us/a/img442/9863/example3y.png。

The final result, if the 'active' property is true and the chosen color is green, can be something like this:

如果“活动”属性为真,选择的颜色为绿色,最后的结果可能是这样的:

example2 http://imageshack.us/a/img836/1968/example2c.png.

example2 http://imageshack.us/a/img836/1968/example2c.png。

#2


0  

Both PNG and SVG images support alpha channel (i.e. transparency), so, why don't you just put your SVG (with transparent parts where you wanto to see your background) over your PNG background?

PNG和SVG图像都支持alpha通道(即透明度),因此,为什么不将SVG(在希望看到背景的透明部分)放在PNG背景上呢?

Or even the other way around... you could put you PNG parts (with transparent "holes") over your SVG image.

或者反过来……您可以将PNG部件(带有透明的“孔”)放在SVG图像上。