2

I don't understand the behavior of opacity in the following code!

import QtQuick 2.4

Rectangle {
    id: root
    width: 640; height: 480

    Rectangle {
        id: wrapper
        width: 600; height:440
        anchors.centerIn: parent
        color: "black"
        opacity: 0.5

        Rectangle {
            id: belowcover
            width: cover.width / 2
            height: cover.height / 2
            anchors.centerIn: parent
            color: "green"
            z: 1
        }

        Rectangle {
            id: cover
            width: root.width / 2
            height: root.height / 2
            anchors.centerIn: parent
            color: "red"
            z: 1
        }

        Rectangle {
            id: seen
            width: 100; height: 100
            radius: width
            color: "blue"
            z: -1
        }
    }
}

The wrapper has opacity of 0.5 so that I could see through it in order to see the circle seen. But both cover and belowcover have opacity of 1, and as belowcover is smaller than cover, it should not be seen (or rather I expect it not to be seen, or am I missing something?). But both cover and belowcover are seen. I want only the circle to be seen through wrapper, and belowcover is to remain hidden below cover. How can I do this? I have observed that setting the z of cover higher than that of belowcover does not make the latter hidden.

Edit: I have observed that when opacity of parent is set to less than 1, the children objects become less opaque, even though their opacity remains at 1, as seen when printed to console. I don't understand why.

Sнаđошƒаӽ
  • 16,753
  • 12
  • 73
  • 90
  • 3
    Have a look at [this](http://stackoverflow.com/questions/9204226/qml-opacity-inheritance/26998032#26998032) question about opacity and the related answer. Generally speaking opacity is *always* inherited from the parent, i.e. you have to set a common `item` parent with `opacity: 1` to tune the opacity of the children. Also [`layer`s](http://doc.qt.io/qt-5/qml-qtquick-item.html#item-layers) can help in certain cases but at an higher cumputational cost. – BaCaRoZzo Mar 10 '15 at 16:29
  • Thanks. So `opacity` goes along the same line as other properties like `x`, `y`, etc. Thus, even though child *has* `opacity` of 1(analogous to `x` value of 0, when absolute `x` may not be 0), it is relative to that of the parent. Nice consistency, though confused me initially! I think you should move your comment to answers for future readers. – Sнаđошƒаӽ Mar 10 '15 at 17:51
  • The choice about opacity is both a consistency choice (a not visible control should have all its children not visible) and a performance choice (layered rendering is costly). Well, I didn't answer because I'm quite sure this question is a duplicate...just can't find the duplicate! :D – BaCaRoZzo Mar 10 '15 at 22:47
  • 1
    ok, here is the duplicate: http://stackoverflow.com/questions/9204226/qml-opacity-inheritance I found it for you ;-) – Sнаđошƒаӽ Jun 02 '15 at 13:43

1 Answers1

3

The reason why a child having opacity of 1 yet appearing to have transparency when its parent has opacity less than 1 is: opacity goes along the same line as other properties like x, y, etc. Thus, even though child has opacity of 1, it is relative to that of the parent. So if parent has opacity 0.5, and child has opacity of 1, then absolute opacity value of child is actually 0.5. Another child with opacity of 0.5 actually has opacity of 0.5x0.5=0.25. This is analogous to x value of child being 0, when absolute x may not be 0. This design preserves consistency throughout the API.

There are several work-arounds. The one I prefer most is to use semi-transparent colors for the parent. Try setting the color of wrapper to color: "#88000000". You can no longer see the green rectangle belowcover. To see that, you have to set the opacity of cover to some value less than 1, which means cover is opaque. That is how I actually solved my problem.

However, if the parent is an image, then this can't be applied. Then you have to resort to some other techniques. For example:

  1. Using layer. Set layer.enabled: true for parent.
  2. By changing the parent when immediate parent has opacity less than 1.
  3. Many other techniques are listed here.
Sнаđошƒаӽ
  • 16,753
  • 12
  • 73
  • 90