我想在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
}
}
这是我从this帖子中得到的一个想法。但是,此示例仅在root
的大小明显大于myRectangle
并且我不希望这样的情况下才有效。我需要例如一个200x10
正方形,其中阴影均匀分布在矩形的边缘。我为InnerShadow
属性尝试了各种值,但我无法接近我想要的效果。
可以使用QML
来实现吗?
答案 0 :(得分:2)
使用效果的“正确”方法 - 所需的引号应该是这样的:
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
}
}
}
最终代码示例的结果窗口:
答案 1 :(得分:1)
InnerShadow元素就像QML中的大多数图形效果元素一样,GLSL着色器,它找到边缘的方式是寻找透明和非透明之间的过渡。如果将滤镜应用于完全实心的图形元素,则无法找到任何边缘,因此不会出现阴影。这与Photoshop滤镜的工作方式完全相同,它还通过扫描从透明到非透明的边缘来查找边缘(如您提供的示例中所示)。它可以将图形区域的边缘视为隐式边缘,但这将极大地限制可用性。这是InnerShadow的来源。根据快速属性,它再次使用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
}
}