Yayin Story Studio logo Yayin Story Studio 项目文档
回到主页 用户手册

Visindigo::Widgets::LiquidGlassEffect Class

class Visindigo::Widgets::LiquidGlassEffect

一个提供液态玻璃效果的图形效果类. 详情...

头文件: #include <Widgets/LiquidGlassEffect.h>
自以下版本: Visindigo 0.13.0

公开类型

(自 Visindigo 0.13.0 引入) enum class BackgroundPolicy { Render, CustomImage }
(自 Visindigo 0.13.0 引入) enum class EffectType { Distort, Blur, All }
flags EffectTypes
(自 Visindigo 0.13.0 引入) enum class PositionPolicy { ParentLocalGeometry, ParentGlobalGeometry, CustomGeometry }

公开成员函数

(自 Visindigo 0.13.0 引入) LiquidGlassEffect(QWidget *parent = nullptr)
(自 Visindigo 0.13.0 引入) ~LiquidGlassEffect()
(自 Visindigo 0.13.0 引入) virtual void draw(QPainter *painter) override
(自 Visindigo 0.13.0 引入) void setBackgroundImage(const QImage &image)
(自 Visindigo 0.13.0 引入) void setBackgroundPolicy(Visindigo::Widgets::LiquidGlassEffect::BackgroundPolicy policy)
(自 Visindigo 0.13.0 引入) void setBlurRadius(int radius)
(自 Visindigo 0.13.0 引入) void setBorderRadius(int radius)
(自 Visindigo 0.15.0 引入) void setColorMask(const QColor &color, qreal percent)
(自 Visindigo 0.13.0 引入) void setCustomGeometry(const QRect &geometry)
(自 Visindigo 0.13.0 引入) void setEffectTypes(Visindigo::Widgets::LiquidGlassEffect::EffectTypes effects)
(自 Visindigo 0.13.0 引入) void setLiquidDistortRadius(int radius)
(自 Visindigo 0.13.0 引入) void setPositionPolicy(Visindigo::Widgets::LiquidGlassEffect::PositionPolicy policy)

静态公开成员

(自 Visindigo 0.13.0 引入) QImage blurImage(const QImage &image, int radius)
(自 Visindigo 0.15.0 引入) QImage colorMaskImage(const QImage &image, const QColor &color, qreal percent)
(自 Visindigo 0.13.0 引入) QImage distortImage(const QImage &coverdArea, int liquidDistortRadius)

详细说明

LiquidGlassEffect 是一个 QGraphicsEffect 的子类,提供了一种模仿IOS26的液态玻璃的图形效果。 这个实现认为液态玻璃效果主要由两部分组成:模仿液体流动的扭曲效果和模仿玻璃模糊的高斯模糊。用户可以通过设置不同的属性来调整这些效果的强度和外观。

理论上,要完全模仿IOS26的液态玻璃,还至少需要边缘光,但这个实现暂时没有提供边缘光的功能。未来可能会考虑添加这个功能。

此外,这个实现也仅适用于矩形、圆角矩形和圆形的QWidget,异形的QWidget可能无法正确显示效果,暂不考虑支持异形QWidget

Note: 注意,要正确使用这个类,它的父对象必须是将被应用效果的QWidget,否则效果可能无法正确显示。

此类的核心功能:扭曲 和 模糊 也可通过静态函数直接调用,允许用户在不使用QGraphicsEffect的情况下对任意图像应用这些效果。

被模糊源的取得

由于QWidget::render()方法的限制,很多时候其渲染的内容可能丢失下层窗口的内容,因此这个实现提供了两种获取被模糊源的方法:

  • 1. LiquidGlassEffect::BackgroundPolicy::Render:通过调用QWidget::render()方法获取被模糊源的图像。这种方法在大多数情况下效果不错,但在某些特定情况下可能会丢失下层窗口的内容。 尤其在下层窗口本身就含有透明要素时,这种方法可能会导致模糊效果不正确。
  • 2. LiquidGlassEffect::BackgroundPolicy::CustomImage:允许用户直接设置一个自定义的图像作为被模糊源。这种方法可以确保模糊效果的正确性,但需要用户自己提供一个合适的图像。 一般来说,如果用户的窗体含有透明要素并存在多级层叠,这是唯一可能可以正确显示模糊效果的方法。

CustomImage 模式下的PositionPolicy

BackgroundPolicy设置为CustomImage时,PositionPolicy的设置会影响模糊效果的位置,即模糊效果会根据PositionPolicy的设置在CustomImage上进行定位和裁剪:

指的指出的是,CustomGeometry应该至少和控件保持一致的长宽比例,否则可能会导致模糊效果的变形。

效果类型

默认情况下,LiquidGlassEffect会同时应用扭曲和模糊两种效果,但用户也可以通过setEffectTypes()方法选择只应用其中一种效果。这提供了更多的定制选项,允许用户根据自己的需求调整效果的外观。 当扭曲和模糊同时应用时,扭曲效果会先应用于被模糊源的图像,然后模糊效果会应用于已经被扭曲的图像。这种顺序可以确保模糊效果能够正确地模仿液态玻璃的外观。

性能考虑

由于模糊和扭曲效果都可能比较耗费性能,尤其是在较大的半径设置下,因此建议用户在使用这个类时注意性能问题。特别是在需要频繁更新效果的情况下,过大的半径设置可能会导致界面卡顿。

从实现代码的角度来看,模糊的性能永远且一定差于扭曲,因此用户在设置模糊半径时应该谨慎考虑是否应该使用过大的模糊半径,以避免性能问题。

此类的模糊采用的是X-Y分解和整形计算的高斯模糊,虽然性能相较于直接卷积的高斯模糊有了很大的提升,但仍然是相当重的操作。

成员类型文档

[since Visindigo 0.13.0] enum class LiquidGlassEffect::BackgroundPolicy

定义了获取被模糊源的方法.

ConstantValueDescription
Visindigo::Widgets::LiquidGlassEffect::BackgroundPolicy::Render0指示此类直接从QWidget::render()获取被模糊源
Visindigo::Widgets::LiquidGlassEffect::BackgroundPolicy::CustomImage1指示此类使用用户提供的自定义图像作为被模糊源

这个enum 从 Visindigo 0.13.0 开始支持。

[since Visindigo 0.13.0] enum class LiquidGlassEffect::EffectType
flags LiquidGlassEffect::EffectTypes

定义了液态玻璃效果的类型.

ConstantValueDescription
Visindigo::Widgets::LiquidGlassEffect::EffectType::Distort0x01扭曲效果,模仿液体流动的效果。
Visindigo::Widgets::LiquidGlassEffect::EffectType::Blur0x02模糊效果,模仿玻璃模糊的效果。
Visindigo::Widgets::LiquidGlassEffect::EffectType::AllDistort | Blur同时应用扭曲和模糊效果,扭曲永远优先于模糊。

这个enum 从 Visindigo 0.13.0 开始支持。

EffectTypes 类型是 QFlags<EffectType> 的一个类型别名。它存储了多个 EffectType 值的OR组合,可供安全计算。

[since Visindigo 0.13.0] enum class LiquidGlassEffect::PositionPolicy

定义了模糊效果在CustomImage上的定位和裁剪方式.

ConstantValueDescription
Visindigo::Widgets::LiquidGlassEffect::PositionPolicy::ParentLocalGeometry0模糊效果的位置和大小与父对象的本地几何形状相匹配
Visindigo::Widgets::LiquidGlassEffect::PositionPolicy::ParentGlobalGeometry1模糊效果的位置和大小与父对象在屏幕上的全局几何形状相匹配
Visindigo::Widgets::LiquidGlassEffect::PositionPolicy::CustomGeometry2模糊效果的位置和大小由用户通过setCustomGeometry()方法设置的自定义几何形状决定

这个enum 从 Visindigo 0.13.0 开始支持。

成员函数文档

[explicit, since Visindigo 0.13.0] LiquidGlassEffect::LiquidGlassEffect(QWidget *parent = nullptr)

parent 父窗口,且必须为将被应用效果的QWidget,否则效果可能无法正确显示。 构造函数。

这个function 从 Visindigo 0.13.0 开始支持。

[noexcept, since Visindigo 0.13.0] LiquidGlassEffect::~LiquidGlassEffect()

析构函数。

这个function 从 Visindigo 0.13.0 开始支持。

[static, since Visindigo 0.13.0] QImage LiquidGlassEffect::blurImage(const QImage &image, int radius)

对图像进行高斯模糊处理。 image 要模糊的图像。 radius 模糊效果的半径,值越大模糊效果越明显。

此函数不提供sigma的手动设置,其sigma采用

sigma = 0.3 * ((radius - 1) * 0.5 - 1) + 0.8

来计算,这个公式是OpenCV使用的经验公式,可以在不同半径下得到比较自然的模糊效果。

这个function 从 Visindigo 0.13.0 开始支持。

[static, since Visindigo 0.15.0] QImage LiquidGlassEffect::colorMaskImage(const QImage &image, const QColor &color, qreal percent)

对图像进行颜色遮罩处理。 image 要处理的图像。color 遮罩的颜色,决定了模糊效果的色调。percent 遮罩的透明度,值越大遮罩越透明,默认1。

这个function 从 Visindigo 0.15.0 开始支持。

[static, since Visindigo 0.13.0] QImage LiquidGlassEffect::distortImage(const QImage &coverdArea, int liquidDistortRadius)

对图像进行液体扭曲处理。 coverdArea 要扭曲的图像。 liquidDistortRadius 扭曲效果的半径,值越大扭曲效果越明显。 此函数通过对图像的边缘区域进行基于正弦函数的坐标偏移来实现液体流动的效果。 扭曲半径决定了边缘区域的宽度,半径越大,扭曲效果越明显。

为了保持性能,扭曲效果仅应用于图像的边缘区域,而图像的中心部分保持不变。 这种方法可以在不显著增加计算量的情况下提供明显的液体流动效果。

当扭曲半径超过图像最短边的一半时,内部会自动按最短边的一半进行扭曲,且不改变用户设置值。

此外,这个扭曲不为不同颜色分量提供不同强度的扭曲以形成色散,因为总的来说色散对于液态玻璃效果的贡献非常有限, 但性能损耗却相对较大,因此这个实现没有提供色散效果。

与此同时,由于液态玻璃通常需要模糊效果,本质上算是一种平滑处理,因此考虑到综合性能, 这个扭曲实现在采样的时候没有单独进行插值计算,因此单独使用时可能会出现锯齿状的边缘。

这个function 从 Visindigo 0.13.0 开始支持。

[override virtual, since Visindigo 0.13.0] void LiquidGlassEffect::draw(QPainter *painter)

重写了QGraphicsEffect的draw()方法,在其中实现了液态玻璃效果的绘制逻辑。 painter 用于绘制效果的QPainter对象。

这个function 从 Visindigo 0.13.0 开始支持。

[since Visindigo 0.13.0] void LiquidGlassEffect::setBackgroundImage(const QImage &image)

设置被模糊源的图像,仅在BackgroundPolicyCustomImage时有效。 image 用于模糊的图像。

这个function 从 Visindigo 0.13.0 开始支持。

[since Visindigo 0.13.0] void LiquidGlassEffect::setBackgroundPolicy(Visindigo::Widgets::LiquidGlassEffect::BackgroundPolicy policy)

设置获取被模糊源的方法。 policy 获取被模糊源的方法,决定了模糊效果的来源。

这个function 从 Visindigo 0.13.0 开始支持。

[since Visindigo 0.13.0] void LiquidGlassEffect::setBlurRadius(int radius)

设置模糊效果的半径,单位为像素。 radius 模糊效果的半径,值越大模糊效果越明显。 出于性能考虑,建议不要设置过大的模糊半径,尤其是在较大的控件上。

这个function 从 Visindigo 0.13.0 开始支持。

[since Visindigo 0.13.0] void LiquidGlassEffect::setBorderRadius(int radius)

设置边框半径,单位为像素。 radius 边框的半径,值越大边框越圆润。 如果被应用效果的控件具有圆角,那么就应该同步设置此值以避免输出时溢出应有的视觉边界。

这个function 从 Visindigo 0.13.0 开始支持。

[since Visindigo 0.15.0] void LiquidGlassEffect::setColorMask(const QColor &color, qreal percent)

设置颜色遮罩。 color 遮罩的颜色,决定了模糊效果的色调。 percent 遮罩的透明度,值越大遮罩越透明,默认1。 颜色遮罩会在模糊效果之后应用,可以用来调整模糊效果的整体色调和透明度,从而更好地模仿液态玻璃的外观。

这个function 从 Visindigo 0.15.0 开始支持。

[since Visindigo 0.13.0] void LiquidGlassEffect::setCustomGeometry(const QRect &geometry)

设置自定义几何形状,仅在PositionPolicyCustomGeometry时有效。 geometry 自定义的几何形状,决定了模糊效果在CustomImage上的位置和大小。

这个function 从 Visindigo 0.13.0 开始支持。

[since Visindigo 0.13.0] void LiquidGlassEffect::setEffectTypes(Visindigo::Widgets::LiquidGlassEffect::EffectTypes effects)

设置效果类型 effects 要应用的效果类型,可以是EffectType的任意组合。

这个function 从 Visindigo 0.13.0 开始支持。

[since Visindigo 0.13.0] void LiquidGlassEffect::setLiquidDistortRadius(int radius)

设置液体扭曲效果的半径,单位为像素。 radius 扭曲效果的半径,值越大扭曲效果越明显。 当扭曲半径超过控件最短边的一半时,内部会自动按最短边的一半进行扭曲,且不改变用户设置值。

这个function 从 Visindigo 0.13.0 开始支持。

[since Visindigo 0.13.0] void LiquidGlassEffect::setPositionPolicy(Visindigo::Widgets::LiquidGlassEffect::PositionPolicy policy)

设置模糊效果的位置策略,仅在BackgroundPolicyCustomImage时有效。 policy 模糊效果的位置策略,决定了模糊效果在CustomImage上的定位和裁剪方式。

这个function 从 Visindigo 0.13.0 开始支持。