QML 的 InnerShadow
用于在元素内部边缘添加阴影效果,常模拟凹陷、压痕或内嵌的立体感,适用于按钮、面板、输入框等 UI 元素。以下是其使用技巧和关键点:
1. 基本用法
import QtQuick 2.15
import QtQuick.Effects 1.15 // 引入效果模块
Rectangle {
width: 200
height: 100
color: "white"
radius: 10 // 圆角矩形
// 启用图层并应用内阴影
layer.enabled: true
layer.effect: InnerShadow {
anchors.fill: parent
radius: 8 // 模糊半径
samples: 16 // 采样数(影响平滑度)
color: "#60000000" // 阴影颜色(建议带透明度)
horizontalOffset: 3 // 水平偏移
verticalOffset: 3 // 垂直偏移
spread: 0.2 // 阴影扩散比例(0.0 ~ 1.0)
cached: true // 启用缓存优化性能
}
}
关键属性:
radius
:模糊半径,值越大阴影越模糊。samples
:采样数,通常设为radius * 2
,值越高阴影越平滑(但性能消耗增加)。color
:阴影颜色,推荐使用带 Alpha 通道的颜色(如#40000000
)。horizontalOffset
/verticalOffset
:阴影偏移方向,正值向元素内部右下偏移。spread
:控制阴影的扩散比例,0.0
为柔和过渡,1.0
为硬边缘。cached
:启用缓存以提升静态阴影的性能。
2. 调整内阴影效果
(1) 模拟不同光照方向
通过调整偏移量改变阴影方向,模拟光源位置:
InnerShadow {
horizontalOffset: -3 // 向左偏移
verticalOffset: -3 // 向上偏移
color: "#80000000"
}
(2) 结合圆角形状
当元素有 radius
或复杂形状时,阴影会自动适应边缘:
Rectangle {
width: 150
height: 150
radius: 75 // 圆形
layer.effect: InnerShadow { /* ... */ }
}
(3) 透明元素的内阴影
确保元素内容非空白(如设置背景色),否则阴影可能不可见:
Image {
source: "transparent_image.png"
layer.enabled: true
layer.effect: InnerShadow { /* ... */ }
}
3. 动态效果与交互
(1) 点击凹陷效果
Rectangle {
id: button
width: 120
height: 40
color: "#f0f0f0"
property bool pressed: false
layer.effect: InnerShadow {
radius: button.pressed ? 4 : 8
verticalOffset: button.pressed ? 1 : 3
color: button.pressed ? "#20000000" : "#60000000"
Behavior on radius { NumberAnimation { duration: 100 } }
}
MouseArea {
anchors.fill: parent
onPressed: button.pressed = true
onReleased: button.pressed = false
}
}
(2) 动态颜色和模糊
通过动画或状态改变属性:
InnerShadow {
id: innerShadow
radius: 8
color: "transparent"
SequentialAnimation on color {
loops: Animation.Infinite
ColorAnimation { to: "#60000000"; duration: 500 }
ColorAnimation { to: "transparent"; duration: 500 }
}
}
4. 性能优化
- 合理设置
samples
:通常设为radius + 8
,平衡平滑度与性能(如radius: 8, samples: 16
)。 - 启用
cached
:对静态阴影启用缓存(cached: true
)。 - 避免高频更新:动态阴影属性(如动画)可能导致 GPU 负载增加。
5. 常见问题
(1) 阴影不显示
- 检查
layer.enabled
是否设为true
。 - 确认
color
的 Alpha 值非零(如#20000000
)。 - 确保元素尺寸足够大,且偏移量未超出范围。
(2) 模糊效果不自然
- 增加
samples
值(如从16
改为24
)。 - 调整
spread
值(0.3
到0.6
更接近自然过渡)。
(3) 边缘锯齿
- 启用
layer.smooth: true
以抗锯齿。 - 提高
layer.textureSize
(如Qt.size(1024, 1024)
)。
6. 进阶技巧
(1) 多重内阴影叠加
通过组合多个 InnerShadow
实现深度效果:
layer.effect: MultiEffect {
anchors.fill: parent
innerShadowEnabled: true
innerShadowColor: "#40000000"
innerShadowBlur: 0.5
innerShadowOffset: Qt.point(2, 2)
// 注意:Qt6 中 MultiEffect 更高效
}
(2) 文字内阴影
Text {
text: "Inner Shadow"
font.pixelSize: 32
layer.enabled: true
layer.effect: InnerShadow {
radius: 4
samples: 8
color: "#40000000"
verticalOffset: 2
}
}
(3) 自定义形状阴影
通过 OpacityMask
裁剪阴影形状:
Rectangle {
width: 200
height: 200
radius: 20
layer.enabled: true
layer.effect: InnerShadow { /* ... */ }
}
总结
- 核心作用:增强 UI 元素的内部立体感,适用于凹陷、压痕等视觉效果。
- 关键属性:
radius
(模糊)、offset
(方向)、spread
(硬度)。 - 适用场景:按钮、输入框、卡片式设计、图标交互反馈。
- 性能贴士:合理控制
samples
和动画复杂度,静态阴影启用缓存。