QML Opacity Inheritance

12,063

Solution 1

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.

Solution 2

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.

Solution 3

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.

Solution 4

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.

Solution 5

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
            }
        }
    }
}
Share:
12,063
aqua boy
Author by

aqua boy

Updated on June 04, 2022

Comments

  • aqua boy
    aqua boy about 2 years

    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.

  • Avio
    Avio about 11 years
    I can confirm this behavior even now. Frankly, I can't see a reason for such a choice, I suspect it's a bug.
  • TheHuge_
    TheHuge_ about 11 years
    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.
  • Avio
    Avio about 11 years
    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?
  • TheHuge_
    TheHuge_ about 11 years
    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.
  • Avio
    Avio about 11 years
    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.
  • TheHuge_
    TheHuge_ about 11 years
    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.
  • jdo
    jdo almost 11 years
    If you can assign a single color directly (not a composite item and not an image), this solution is perfect.
  • mchiasson
    mchiasson over 8 years
    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
    mchiasson over 8 years
    the color property in QML is ARGB, not RGBA. Change your color to #FA000000 and it will work.
  • ManuelH
    ManuelH over 8 years
    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.
  • While-E
    While-E almost 6 years
    Thank you, this solved my issue. I actually just set #00000000, and it worked perfectly.
  • Mohammad Kanan
    Mohammad Kanan over 3 years
    Nope! 'layer.enabled' wont do that
  • Mohammad Kanan
    Mohammad Kanan over 3 years
    Layer Opacity vs Item Opacity. So layers.enabled controls item by item alpha blending
  • pooya13
    pooya13 about 3 years
    To emphasize, the transparency digits are the first two digits. Different alpha values can be found in this chart: gist.github.com/lopspower/03fb1cc0ac9f32ef38f4