我想在QML
中创建一个带有内部阴影的矩形,类似于Photoshop
所做的:
QML
有InnerShadow
,但我无法达到这个效果。离我最近的就是这个
import QtQuick 2.0
import QtGraphicalEffects 1.0
Item {
id: root
width: 300
height: 300
Rectangle {
id: myRectangle
anchors.centerIn: parent
width: 100
height: 100
color: "grey"
}
InnerShadow {
anchors.fill: root
cached: true
horizontalOffset: 0
verticalOffset: 0
radius: 16
samples: 32
color: "#b0000000"
smooth: true
source: root
}
}
这是我从这帖子中得到的一个想法。但是,这个示例只在root
比myRectangle
大得多的情况下起作用,我不想这样做。我需要一个200x10
正方形,其中阴影均匀地分布在矩形的边缘上。我为InnerShadow
属性尝试了各种类型的值,但是我甚至无法达到我想要的效果。
这能用QML
来实现吗?
发布于 2015-04-08 23:21:09
使用效果所需的“正确”方法--引号--应该是这样的:
import QtQuick 2.0
import QtGraphicalEffects 1.0
Item {
id: root
width: 300
height: 300
Item {
id: src
anchors.fill: parent
Rectangle {
id: myRectangle
anchors.centerIn: parent
width: 100
height: 100
color: "grey"
}
}
InnerShadow {
anchors.fill: src
cached: true
horizontalOffset: 0
verticalOffset: 0
radius: 16
samples: 32
color: "#b0000000"
smooth: true
source: src
}
}
正如您所看到的,它与另一个问题中提出的解决方案略有不同。使用这段代码,您仍然需要留下2个像素,以获得效果,这将导致白色边框(或任何背景颜色)。通过将root
更改为Rectangle
,可以很容易地解决这个问题。
最后一个示例解决方案如下。显然,您可以提取root
组件(以及相关的子组件),并将其放入Component
或不同的.qml
文件中供以后使用。
import QtQuick 2.4
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0
Window {
width: 200
height: 20
visible: true
Rectangle { // was Item
id: root
anchors.fill: parent
color: "grey"
Item {
id: src
anchors.fill: parent
Rectangle {
id: myRectangle
anchors.centerIn: parent
width: root.width - 2
height: root.height - 2
color: "lightgrey"
}
}
InnerShadow {
anchors.fill: src
cached: true
horizontalOffset: 0
verticalOffset: 0
radius: 16
samples: 32
color: "#b0000000"
smooth: true
source: src
}
}
}
最终代码示例的结果窗口:
发布于 2016-11-26 13:16:48
InnerShadow元素类似于GLSL着色器QML中的大多数图形效果元素,它寻找边缘的方法是寻找透明和非透明之间的过渡。如果将过滤器应用于一个完全实心的图形元素,它将找不到任何边缘,因此没有阴影。这与Photoshop过滤器的工作方式完全一样,它还通过扫描从透明到非透明的边缘来查找边缘(如您提供的示例)。它可以将图形区域的边缘视为隐式边缘,但这将大大限制可用性。这是InnerShadow的源代码。它根据fast属性再次使用FastInnerShadow或GaussianInnerShadow。
如果您想要一个只需将其添加到现有元素而不必考虑在透明和非透明边缘之间进行转换的实现,则可以使用以下方法:
Rectangle {
id: myRectangle
anchors.centerIn: parent
width: 300
height: 300
color: "#AAAAAA"
}
Item {
id: _innerShadow
property var shadowSource: myRectangle
property var color: "#B0000000"
anchors.fill: shadowSource
Item {
id: _shadowMarker
//width: source.width+1; height: source.height+1
anchors.fill: parent;
anchors.margins: -10
ColorOverlay {
anchors.fill: _shadowMarker;
anchors.margins: 10
source: _innerShadow.shadowSource
color: "#00000000"
}
visible: false
}
InnerShadow {
anchors.fill: _shadowMarker
cached: true
horizontalOffset: 0
verticalOffset: 0
radius: 16
samples: 32
color: _innerShadow.color
smooth: true
source: _shadowMarker
}
}
发布于 2021-11-13 21:56:18
这是我的解决办法
GoodInnerShadow.qml
///
/// Same as InnerShadow QML type, with the following differences
///
/// InnerShadow requires transparent space to be surrounding the
/// item that you want to make an inner shadow for. GoodInnerShadow
/// does not require this.
///
/// InnerShadow draws the source with the shadow. GoodInnerShadow
/// draws just the shadow
///
import QtQuick 2.15
import QtGraphicalEffects 1.0
Item {
id: root
anchors.centerIn: source
width: source.width
height: source.height
required property var source
property color color: "#50ffffff"
property double radius: 12
property double spread: .8
Item{
id: sourceMaskWithPadding
visible: false
anchors.centerIn: parent
width: root.source.width + shadowOfInverse.samples * 2
height: root.source.height + shadowOfInverse.samples * 2
OpacityMask {
id: sourceMask
anchors.centerIn: parent
width: root.source.width
height: root.source.height
maskSource: root.source
source: root.source
}
}
Rectangle {
id: coloredRect
visible: false
color: root.color
anchors.fill: sourceMaskWithPadding
}
OpacityMask {
id: sourceInverse
visible: false
anchors.fill: coloredRect
source: coloredRect
maskSource: sourceMaskWithPadding
invert: true
}
DropShadow {
id: shadowOfInverse
visible: false
anchors.fill: sourceInverse
source: sourceInverse
radius: root.radius
samples: radius * 2 + 1
color: root.color
spread: root.spread
}
OpacityMask {
id: sourceInnerShadow
anchors.fill: sourceMaskWithPadding
maskSource: sourceMaskWithPadding
source: shadowOfInverse
}
}
示例使用
import QtQuick 2.15
Item {
width: 400
height: 300
Rectangle {
id: myRect
anchors.centerIn: parent
width: 300
height: 100
color: "lightgray"
}
GoodInnerShadow {
source: myRect
color: "#aa000000"
spread: .5
radius: 16
}
}
结果
https://stackoverflow.com/questions/29517596
复制相似问题