QML不透明度继承

20

在QML中,我如何防止子元素继承其父元素的不透明度?我想要为父元素和其子元素设置不同的不透明度值。

9个回答

16

我认为,一种方法是使用半透明颜色,如此处所述,而不是使用不透明度。

例如,使用四元色代码 #800000FF 来表示半透明蓝色。


如果您可以直接分配单个颜色(而不是复合项或图像),那么这个解决方案就是完美的。 - jdo
谢谢,这解决了我的问题。我实际上只是设置了#00000000,它完美地工作了。 - While-E
1
强调一下,透明度数字是前两位。不同的 alpha 值可以在此图表中找到:https://gist.github.com/lopspower/03fb1cc0ac9f32ef38f4 - pooya13

15
实际上,将父元素的layer.enabled: true设置为真即可实现此功能。整个元素将被渲染到缓冲区,并将opacity应用于生成的缓冲区(整个图层一次性应用)。
请参见http://doc.qt.io/qt-5/qml-qtquick-item.html#layer.enabled-prop
示例代码:
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'
    }
}

那是一个解决方案,但在启用图层时,请确保知道自己在做什么。

另一个可能的解决方案是使用着色器效果。

感谢 #qt@freenode 上的 peppe。


不行!'layer.enabled' 不会做到那样。 - Mohammad Kanan
图层不透明度与项不透明度的区别。因此,layers.enabled 控制每个项的 alpha 混合。 - Mohammad Kanan

10

您不能这样做。元素的不透明度值是相对于其父级元素的,因此如果您编写类似以下代码的内容:

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

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

你会发现这两个矩形具有相同的不透明度。


我现在可以确认这种行为。坦白地说,我看不出这样选择的理由,我怀疑这是一个错误。 - Avio
2
我认为这不是一个 bug。这是许多常见属性(例如:x、y、z)的相同形式。它使您无需使用绝对引用来排列每个项目。 - TheHuge_
1
如果您将一组项目的不透明度设置为0.5,则对我(以及Qt开发人员)来说,这意味着您希望将该值设置为组中所有项目。否则,您应该只将此值设置为您想要的项目。 - TheHuge_
您可以在根元素中添加自定义的“defaultOpacity”属性,并将每个子元素的不透明度指向该属性,或者在“例外情况”中设置特定值。当然,我并不是说这是处理不透明度继承的唯一正确方式;这只是对我来说是有意义的。 - TheHuge_
1
是的...这就是不透明度在场景图中通常的工作方式:一个节点的不透明度是该节点的本地不透明度乘以其祖先节点的不透明度。因此,如果父节点具有0.5的本地不透明度,而子节点具有1.0的本地不透明度,则子节点的结果不透明度将是父节点的不透明度(0.5)x 子节点的本地不透明度(1.0)= 0.5。然而,我希望将不透明度值设置为2.0会起作用,因为0.5 * 2.0 = 1.0。我尝试了一下,但不幸的是它没有起作用。看起来Qt太早地将不透明度值限制在0..1之间了... :( - mchiasson
显示剩余2条评论

8

我刚刚遇到了这个问题。使用的是Qt 5.1.0。

在我的情况下,我有一个Rectangle元素,它具有opacity: 0.6和一个子Image元素。 Image继承了透明度 - 这是不期望的。

为了解决这个问题,我将主要的Rectangle封装在一个Item元素中。从Rectangle传递大小/位置定义到外部Item。将Image移到Rectangle之外。

最后,我有Item作为主要父级,RectangleImage并排在Item内。

只有Rectangle维持了不透明度0.6,因此Rectangle具有透明度,而Image是完全不透明的。


4

这是可能的!你需要在Component.onCompleted作用域中测试父级的不透明度。如果它为0,则需要将您的对象的父级更改为当前父级的父级。

示例:

Item{
    id:root

    Item{
        id:currentParent
        opacity: 0
        Item{
            id:item
            Component.onCompleted:{
                if(parent.opacity === 0)
                    item.parent = currentParent.parent
            }
        }
    }
}

3

您无法阻止子元素从其父元素继承不透明度。

我的个人解决方法是更改这个:

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

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

转化为:

Item {
    width: 200; height: 100

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

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

}

或者这样(只有在父级是纯色的情况下才可能):
Rectangle {
    color: "#7FFF0000" // 50% transparent red
    opacity: 0.5
    width: 200; height: 100

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

2

无法实现此操作,但可以使用Qt.lighter(color,opacity)更改颜色。

例如:

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

  Rectangle {
    color: Qt.lighter("blue",1)
    width: 100; height: 100
  }
}

2
我认为这是不可能的。你需要创建两个兄弟元素,并按照你的意愿更改它们的不透明度。

0
我在Qt 4.8.6中也遇到了这个问题。
在我特定的情况下,我希望顶层元素是20%透明度的黑色,但其子元素不受父元素任何透明度设置的影响。
由于QML的继承机制,透明度无效。
但我能够使用Qml Qt对象的rgba函数。这让我得到了我想要的效果,父元素现在是20%透明,但子元素不受影响。
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...
}

注意:我也尝试直接使用RGBA颜色代码,正如之前的帖子中提到的,但是没有成功。
示例:
color: "#000000FA" // Supposed to be semi transparent, but always transparent, regardless of the alpha value

设置任何其他RGBA值的alpha值都可以正常工作,但对于纯黑色却不行。


1
QML中的颜色属性是ARGB,而不是RGBA。将您的颜色更改为#FA000000,它就可以工作了。 - mchiasson
你是正确的。也许是因为我之前一直在使用Qt.rgba(..),所以当时我把颜色类型的格式也想成了相同的。 - ManuelH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接