20

In QML, how can I prevent a child element from inheriting the opacity from its parent? I want to set different opacity values for the parent and it's child element.

aqua boy
  • 419
  • 2
  • 4
  • 7

9 Answers9

16

I think, one way would be to use semi transparent colors as described here instead of opacity.

e.g. using quad color code like #800000FF for semi transparent blue.

Sнаđошƒаӽ
  • 16,753
  • 12
  • 73
  • 90
pareshdbest
  • 161
  • 1
  • 3
  • If you can assign a single color directly (not a composite item and not an image), this solution is perfect. – jdo Jul 09 '13 at 13:45
  • Thank you, this solved my issue. I actually just set #00000000, and it worked perfectly. – While-E Aug 10 '18 at 14:28
  • 1
    To emphasize, the transparency digits are the **first two** digits. Different alpha values can be found in this chart: https://gist.github.com/lopspower/03fb1cc0ac9f32ef38f4 – pooya13 Apr 20 '21 at 22:55
15

Actually, setting layer.enabled: true for the parent element does the thing for me. The whole element is rendered to the buffer, and opacity is applied to the resulting buffer (to the whole layer at once).

See http://doc.qt.io/qt-5/qml-qtquick-item.html#layer.enabled-prop

Example code:

Rectangle {
    width: 400
    height: 200
    opacity: 0.5
    layer.enabled: true
    Rectangle {
            width: parent.width
            height: parent.height
            color: 'red'
    }
    Rectangle {
            width: parent.width / 2
            height: parent.height
            color: 'blue'
    }
}

That is a solution, but make sure that you know what you are doing when enabling layering.

Another possible solution would be using a shadereffect.

Thanks to peppe on #qt@freenode.

ChALkeR
  • 151
  • 2
  • 5
10

You can't. Items opacity value is relative to their parents one, so if you code something like

Rectangle {
  color: "red"
  opacity: 0.5
  width: 200; height: 100

  Rectangle {
    color: "blue"
    opacity: 1
    width: 100; height: 100
  }
}

You will see that the two rectangles have the same opacity.

TheHuge_
  • 1,039
  • 17
  • 29
  • I can confirm this behavior even now. Frankly, I can't see a reason for such a choice, I suspect it's a bug. – Avio Jun 06 '13 at 09:16
  • 2
    I don't think it's a bug. It's the same form many common properties (e.g.: x, y, z). It allows you not to arrange every Item using absolute references. – TheHuge_ Jun 10 '13 at 07:37
  • I tried to open a bug against QtQml, it has been closed in minutes, so it seems that Qt folks are of your same opinion. But I'm still skeptik about this matter. If I write a line of code, I don't want it to be ignored in first place, secondly if it has to be ignored, I'd like to be warned that my code has not effect. But, again, I can't see a reason why, if a block of elements have opacity 0.5, I can't make just one of it having opacity 1. And if they are logically grouped as children of the main container, why should I make just one of it a sibling? – Avio Jun 10 '13 at 07:58
  • 1
    If you set the opacity of a group of Items to 0.5, it means to me (and to Qt guys) that you want to set that value to all the Items in the group. Otherwise you should set this value just to the Items you want to. – TheHuge_ Jun 10 '13 at 09:04
  • What I mean is to have the possibility to _add an exception_ to the opacity policy of the group. If you have tens of elements inside a logical group, and you want just only one of it to behave differently from the others, why should you pick it up and place it apart from the others? I mean, the logical hierarchy of the elements exists regardless of the opacity of its members. – Avio Jun 10 '13 at 11:02
  • You can add a custom `defaultOpacity` property to the root, and point the opacity of each child to that or set a specific value in the "exceptional" ones. Of course I'm not sayng this is THE right way of treating the opacity inheritance; it just makes sense to me. – TheHuge_ Jun 10 '13 at 12:10
  • 1
    yeah... that's how opacity typically works in a scene graph: a node's opacity is the node's local opacity multiplied by it's ancestors, opacity. For this reason, if the parent has a local opacity of 0.5 and the child has a local opacity of 1.0, the resulting opacity for the child will be parent's opacity (0.5) x child local opacity (1.0) = 0.5. However, I would expect that putting the opacity value to 2.0 would work, because 0.5 * 2.0 = 1.0. I tried it and it didn't work unfortunately. It looks like Qt is clamping the opacity values between 0 .. 1 too soon... :( – mchiasson Oct 21 '15 at 13:31
8

I've bumped into this issue just now. Using Qt 5.1.0

In my case, I had a Rectangle Element with opacity: 0.6 and a child Image element. The Image was inheriting the transparency - not desired.

To solve it, I enclosed the main Rectangle in an Item element. Passed the size/position definitions from the Rectangle to the outer Item. Moved the Image outside the Rectangle.

In the end, I had Item as the main parent and Rectangle and Image side by side, inside Item.

Only Rectangle maintained the opacity 0.6, so the Rectangle has transparency and Image is fully opaque.

BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82
Nuno Faria
  • 81
  • 1
  • 2
4

It's possible! You need to test in the Component.onCompleted scope the opacity of the parent. If its 0 you need to change the parent of your object to the parent of it's current parent.

Example:

Item{
    id:root

    Item{
        id:currentParent
        opacity: 0
        Item{
            id:item
            Component.onCompleted:{
                if(parent.opacity === 0)
                    item.parent = currentParent.parent
            }
        }
    }
}
Mido
  • 1,092
  • 1
  • 9
  • 14
3

You cannot prevent the child element from inheriting the opacity from its parent.

My personal work around is to change this:

Rectangle {
    color: "red"
    opacity: 0.5
    width: 200; height: 100

    Rectangle {
        color: "blue"
        opacity: 1
        width: 100; height: 100
    }
}

Into this:

Item {
    width: 200; height: 100

    Rectangle {
        anchors.fill: parent
        color: "red"
        opacity: 0.5
    }

    Rectangle {
        color: "blue"
        opacity: 1
        width: 100; height: 100
    }

}

or this (only possible if the parent is a solid color):

Rectangle {
    color: "#7FFF0000" // 50% transparent red
    opacity: 0.5
    width: 200; height: 100

    Rectangle {
        color: "blue"
        opacity: 1
        width: 100; height: 100
    }
}
mchiasson
  • 2,452
  • 25
  • 27
2

it is not possible to do that but you can change their color with

Qt.lighter(color,opacity)

for example

Rectangle {
  color: Qt.lighter("red",.5)
  width: 200; height: 100

  Rectangle {
    color: Qt.lighter("blue",1)
    width: 100; height: 100
  }
}
Mohsen Zahraee
  • 3,309
  • 5
  • 31
  • 45
2

I don't think its possible. you have to make two element sibling and changes its opacity as you wish.

Kunal
  • 3,475
  • 21
  • 14
0

I also ran into this problem with Qt 4.8.6.

In my particular case, I wanted the top level item to be 20% transparent with black color, but have its child elements be unaffected by any opacity/transparency setting from the parent.

Opacity did not work, due to the inheritance mechanism of QML.

But I was able to use the rgba function from the Qml Qt object. This allowed me to get exactly what I wanted, the parent is now 20% transparent, but the child elements are unaffected.

Rectangle {
    width: 400
    height: 400
    color: Qt.rgba(0, 0, 0, 0.2) // Works perfectly, pure black with 20% transparency, equal to 0.2 opacity

    // Unaffacted child elements here...
}

Note: I also tried to use the RGBA color codes directly, as mentioned by a previous poster, but it did not work.

Example:

color: "#000000FA" // Supposed to be semi transparent, but always transparent, regardless of the alpha value

Setting the alpha value for any other RGBA values worked, just not with pure black.

ManuelH
  • 846
  • 1
  • 15
  • 25
  • 1
    the color property in QML is ARGB, not RGBA. Change your color to `#FA000000` and it will work. – mchiasson Oct 23 '15 at 12:16
  • You are correct. Perhaps, because I was working with Qt.rgba(..) previously, I got it stuck in my mind at the time that the color type was using the same format. – ManuelH Oct 23 '15 at 13:18