From 7f63f768737bdb32b0f8b70de4babbb24e2a68d3 Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Tue, 1 Jul 2025 23:41:31 +1000 Subject: [PATCH 1/3] add effects guide --- src/guide/effects.mdx | 463 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 463 insertions(+) create mode 100644 src/guide/effects.mdx diff --git a/src/guide/effects.mdx b/src/guide/effects.mdx new file mode 100644 index 0000000..7c4f16a --- /dev/null +++ b/src/guide/effects.mdx @@ -0,0 +1,463 @@ +--- +title: "Graphical Effects" +index: 7 +--- + +Everyone wants effects in their rice right? Well look no further, @@QtQuick.Effects.MultiEffect +is here! + +# Qt 6 MultiEffect + +Now how do I use this you ask? Well, this guide provides a few examples for common uses of +effects such as drop shadows, colourisation, masks and blurring. + +First and foremost (and arguably the most commonly used), drop shadows! To create a drop shadow, +the [QtQuick.Effects](https://doc.qt.io/qt-6/qtquick-effects-qmlmodule.html) module provides +two components that you can use: @@QtQuick.Effects.RectangularShadow and @@QtQuick.Effects.MultiEffect. + +@@QtQuick.Effects.RectangularShadow is much easier to use and more efficient than +@@QtQuick.Effects.MultiEffect, however it can only be used for rectangular shadows (as the name implies). +On the other hand, @@QtQuick.Effects.MultiEffect can used for most common effects, including all of +the previously mentioned effects. + +### Shadows + +The simplest way to create a rectangular drop shadow is with the @@QtQuick.Effects.RectangularShadow +component. This component essentially creates a rectangle with blurred edges to act as a shadow. To +use this component, you would typically create one below the source component of the shadow. To position +a component beneath another, you can either simply create it before the other component, or use the +@@QtQuick.Item.z property to visually position it below the other component. + +For example: + +```qml +@@QtQuick.Rectangle { + id: rect + + implicitWidth: 100 + implicitHeight: 200 + radius: 30 +} + +@@QtQuick.Effects.RectangularShadow { + anchors.fill: rect // Fill the source rect + radius: rect.radius // Have the same rounding as the source rect + blur: 15 // The blur/radius of the shadow + spread: 2 // The number of pixels from the edges of the rect the shadow extends from + color: "#000000" // The colour of the shadow + z: -1 // Visually positions the shadow behind the source rect +} +``` + +For more complex shapes, you can use the @@QtQuick.Effects.MultiEffect with the +@@QtQuick.Effects.MultiEffect.shadowEnabled property set to `true`. You can then use the +@@QtQuick.Effects.MultiEffect.shadowBlur, @@QtQuick.Effects.MultiEffect.shadowScale, +@@QtQuick.Effects.MultiEffect.blurMax, @@QtQuick.Effects.MultiEffect.blurMultiplier, +@@QtQuick.Effects.MultiEffect.shadowHorizontalOffset, @@QtQuick.Effects.MultiEffect.shadowVerticalOffset, +@@QtQuick.Effects.MultiEffect.shadowOpacity and @@QtQuick.Effects.MultiEffect.shadowColor properties to +tweak the drop shadow looks to your liking. + +Here's a simple example: + +> [!NOTE] +> @@QtQuick.Effects.MultiEffect renders a new visual item alongside the source component, +> meaning displaying the source component as well as the @@QtQuick.Effects.MultiEffect is unecessary +> and wastes CPU cycles. To avoid this, you should either set `visible: false` or `opacity: 0` on +> the source component. The first will prevent it from receiving mouse events while the second won't. + +```qml +@@QtQuick.Rectangle { + id: rect + + implicitWidth: 100 + implicitHeight: 200 + radius: 100 + visible: false +} + +@@QtQuick.Effects.MultiEffect { + anchors.fill: rect + source: rect + shadowEnabled: true // This must be true for the shadow work + blurMax: 32 // This affects the radius of the shadow (this is also affected by `shadowBlur` and `blurMultiplier`) + shadowScale: 1 // This is essentially the same as `RectangularShadow#spread` but as a multiplier of the source's size + shadowColor: "#000000" // The colour of the shadow +} +``` + +### Simple effects + +For simple effects like colourisation, brightness, contrast and saturation, @@QtQuick.Effects.MultiEffect +provides them as easily animatable props. + +```qml +@@QtQuick.Image { + id: img + + source: "/path/to/img" + visible: false +} + +@@QtQuick.Effects.MultiEffect { + anchors.fill: img + source: img + colorization: 1 // The amount of colourisation as a real between 0 and 1 (0 is no colourisation) + colorizationColor: "#ab35a3" // The colour of the colourisation to apply + brightness: 0.3 // The brightness to apply as a real between -1 and 1 (0 is no change) + contrast: 0.5 // The contrast to apply as a real between -1 and 1 (0 is no change) + saturation: 6 // The saturation to apply as a real greater than -1 (0 is no change) +} +``` + +### Masking + +@@QtQuick.Effects.MultiEffect can also do masking. + +> [!NOTE] +> The component you use as the mask source NEEDS to have @@QtQuick.Item.layer.enabled set to `true` +> if it is not a @@QtQuick.ShaderEffectSource or texture provider such as @@QtQuick.Image. +> +> Additionally, the mask source will be scaled to the size of the @@QtQuick.Effects.MultiEffect, +> so you must wrap it in another item for it to be positioned and sized correctly. + +For example: + +```qml +@@QtQuick.Image { + id: img + + source: "/path/to/img" + visible: false +} + +@@QtQuick.Item { + id: mask + + visible: false + layer.enabled: true + + @@QtQuick.Rectangle { + anchors.centerIn: parent + implicitWidth: 200 + implicitHeight: 240 + } +} + +@@QtQuick.Effects.MultiEffect { + anchors.fill: img + source: img + maskSource: mask + maskEnabled: true // This must be true for the mask to work + maskInverted: false // You can use this to invert the masked area + + // These provide antialiasing for the edges of the mask and make it look much better + maskSpreadAtMin: 1 + maskThresholdMin: 0.5 +} +``` + +### Blurring + +Blurring is also done using the @@QtQuick.Effects.MultiEffect component. It is done similarly +to shadows, however instead of setting the @@QtQuick.Effects.MultiEffect.shadowEnabled +property to `true`, you set the @@QtQuick.Effects.MultiEffect.blurEnabled property to `true`. +The blur effect can be customised with the @@QtQuick.Effects.MultiEffect.blur, +@@QtQuick.Effects.MultiEffect.blurMax and @@QtQuick.Effects.MultiEffect.blurMultiplier properties. + +For example: + +```qml +@@QtQuick.Image { + id: img + + source: "/path/to/img" + visible: false +} + +@@QtQuick.Effects.MultiEffect { + anchors.fill: img + source: img + blurEnabled: true + blur: 1 // This affects the radius of the blur (a real between 0 and 1) + blurMax: 32 // This affects the max radius of the blur (i.e. the radius when `blur` is 1) + blurMultiplier: 1 // A multiplier for the blur radius (0 is not multiplied) +} +``` + +### Stacking effects + +The advantage of using a @@QtQuick.Effects.MultiEffect is that you can apply multiple effects +to a component in a single pass. You can do this by simply setting that effect's corresponding enabled +property to `true` and configuring it as shown previously. + +For example, the snippet below applies colourisation, shadow and blur: + +```qml +@@QtQuick.Image { + id: img + + source: "/path/to/img" + visible: false +} + +@@QtQuick.Effects.MultiEffect { + anchors.fill: img + source: img + + // Apply colourisation + colorization: 1 + colorizationColor: "#abc4d3" + + // Apply shadow + shadowEnabled: true + shadowBlur: 1 + shadowColor: "#000000" + + // Apply blur (`blurMax` also affects shadow) + blurEnabled: true + blur: 1 + blurMax: 32 +} +``` + +# Migrating from Qt5Compat + +As of May 26 2025, Qt 5 reached the End of Support state. However, the Qt 5 Core APIs +that were removed in Qt 6 are still available via the [Qt5Compat](https://doc.qt.io/qt-6/qtcore5-index.html) +module. This means that the core APIs (mainly +[Qt5Compat.GraphicalEffects](https://doc.qt.io/qt-6/qtgraphicaleffects5-index.html)) are still +available to use in Qt 6, though new code should use the +[QtQuick.Effects](https://doc.qt.io/qt-6/qtquick-effects-qmlmodule.html) module instead. + +## Differences + +The [Qt5Compat.GraphicalEffects](https://doc.qt.io/qt-6/qtgraphicaleffects5-index.html) +module contains many useful effects such as @@Qt5Compat.GraphicalEffects.DropShadow, +@@Qt5Compat.GraphicalEffects.FastBlur and @@Qt5Compat.GraphicalEffects.OpacityMask. These +do not exist in the [QtQuick.Effects](https://doc.qt.io/qt-6/qtquick-effects-qmlmodule.html) +module, instead they are available using a single @@QtQuick.Effects.MultiEffect component. + +## Why should I migrate? + +Firstly, the [Qt5Compat.GraphicalEffects](https://doc.qt.io/qt-6/qtgraphicaleffects5-index.html) +module is included in Qt 6 primarily for compatibility with Qt 5 applications and it is +recommended to use the [QtQuick.Effects](https://doc.qt.io/qt-6/qtquick-effects-qmlmodule.html) +module in new code instead. + +Additionally, @@QtQuick.Effects.MultiEffect can apply multiple effects on an object in a +single pass, compared to the effects in the +[Qt5Compat.GraphicalEffects](https://doc.qt.io/qt-6/qtgraphicaleffects5-index.html) module. +This means it is more efficient for having multiple effects compared to the old module. + +## Replicating Qt5 Effects in Qt6 + +Below is a list of examples of how to replicate effects from the +[Qt5Compat.GraphicalEffects](https://doc.qt.io/qt-6/qtgraphicaleffects5-index.html) module +using the [QtQuick.Effects](https://doc.qt.io/qt-6/qtquick-effects-qmlmodule.html) module. + +### Colourisation/Brightness/Contrast/Saturation + +The @@QtQuick.Effects.MultiEffect component provides all these effects as properties +(@@QtQuick.Effects.MultiEffect.colorization, @@QtQuick.Effects.MultiEffect.brightness, +@@QtQuick.Effects.MultiEffect.contrast, @@QtQuick.Effects.MultiEffect.saturation). + +Comparatively, the [Qt5Compat.GraphicalEffects](https://doc.qt.io/qt-6/qtgraphicaleffects5-index.html) +module provides these effects as separate effects (@@Qt5Compat.GraphicalEffects.Colorize, +@@Qt5Compat.GraphicalEffects.BrightnessContrast, @@Qt5Compat.GraphicalEffects.HueSaturation). + +### Shadows + +To create shadows for rectangular objects, the +[QtQuick.Effects](https://doc.qt.io/qt-6/qtquick-effects-qmlmodule.html) module provides +a useful component called @@QtQuick.Effects.RectangularShadow. This creates a rectangular +shadow with a configurable size, radius/spread and colour. + +For other shapes, you must use a @@QtQuick.Effects.MultiEffect instead. + +For example, using a @@Qt5Compat.GraphicalEffects.DropShadow: + +```qml +// Note that the source component should not be visible when using DropShadow +// as DropShadow renders a new visual item alongside the source component, +// meaning displaying the source component as well as the DropShadow is unecessary +// and wastes CPU cycles rendering the source component. +@@QtQuick.Rectangle { + id: rect + + implicitWidth: 100 + implicitHeight: 200 + radius: 30 + visible: false +} + +@@Qt5Compat.GraphicalEffects.DropShadow { + anchors.fill: rect + source: rect + radius: 8 + samples: 1 + radius * 2 + color: "#000000" +} +``` + +You can replicate this using a @@QtQuick.Effects.RectangularShadow or a @@QtQuick.Effects.MultiEffect. +You should use @@QtQuick.Effects.RectangularShadow over @@QtQuick.Effects.MultiEffect +when you are able to as they are easier to use and more efficient. + +Using a @@QtQuick.Effects.RectangularShadow: + +```qml +// Note that the RectangularShadow is below the source component of the shadow. +// You can do this either by putting it before the source (like so) +// or by setting the `z` property to less than the source's. +@@QtQuick.Effects.RectangularShadow { + anchors.fill: rect + radius: rect.radius // Affects the radius of the rectangle + blur: 6 // Affects the blur/radius of the shadow + spread: 1 // Affects the scale/spread of the shadow from the edges of the rectangle in pixels + color: "#000000" +} + +// Also note that the actual component should be visible when using a RectangularShadow +// as the shadow is solely a shadow, unlike a MultiEffect. +@@QtQuick.Rectangle { + id: rect + + implicitWidth: 100 + implicitHeight: 200 + radius: 30 +} +``` + +Using a @@QtQuick.Effects.MultiEffect: + +```qml +// Note that the source component should not be visible for the same reason as +// the DropShadow. This applies to all uses of MultiEffect. +@@QtQuick.Rectangle { + id: rect + + implicitWidth: 100 + implicitHeight: 200 + radius: 30 + visible: false +} + +@@QtQuick.Effects.MultiEffect { + anchors.fill: rect + source: rect + shadowEnabled: true // This must be true for the shadow work + blurMax: 32 // This affects the radius of the shadow (this is also affected by `shadowBlur` and `blurMultiplier`) + shadowBlur: 0.5 + shadowScale: 1 // This is essentially the same as `RectangularShadow#spread` but as a multiplier of the source's size + shadowColor: "#000000" +} +``` + +### Blurring + +Previously in Qt 5, you would use a @@Qt5Compat.GraphicalEffects.FastBlur or +@@Qt5Compat.GraphicalEffects.GaussianBlur to blur components. In Qt 6, you should +use a @@QtQuick.Effects.MultiEffect instead. However, it is not possible to replicate +@@Qt5Compat.GraphicalEffects.GaussianBlur using @@QtQuick.Effects.MultiEffect. Instead, +you must use a custom shader with a @@QtQuick.ShaderEffect. + +Using a @@Qt5Compat.GraphicalEffects.FastBlur: + +```qml +@@QtQuick.Image { + id: img + + source: "path/to/image" + visible: false +} + +@@Qt5Compat.GraphicalEffects.FastBlur { + anchors.fill: img + source: img + radius: 32 +} +``` + +Using a @@QtQuick.Effects.MultiEffect: + +```qml +@@QtQuick.Image { + id: img + + source: "path/to/image" + visible: false +} + +@@QtQuick.Effects.MultiEffect { + anchors.fill: img + source: img + blurEnabled: true // This must be true for the blur to work + blur: 1 // Affects the amount of blur + blurMax: 34 // Affects the max radius of the blur (i.e. the radius of the blur when `blur` is 1) +} +``` + +### Masking + +Previously in Qt 5, you would use an @@Qt5Compat.GraphicalEffects.OpacityMask to mask components. In Qt 6, you +should use a @@QtQuick.Effects.MultiEffect with the @@QtQuick.Effects.MultiEffect.maskEnabled property instead. + +Using an @@Qt5Compat.GraphicalEffects.OpacityMask: + +```qml +@@QtQuick.Image { + id: img + + source: "path/to/image" + visible: false +} + +@@QtQuick.Text { + id: mask + + text: "hi" + font.pointSize: 31 + font.bold: true + visible: false +} + +@@Qt5Compat.GraphicalEffects.OpacityMask { + anchors.fill: img + source: img + maskSource: mask +} +``` + +Using a @@QtQuick.Effects.MultiEffect: + +```qml +@@QtQuick.Image { + id: img + + source: "path/to/image" + visible: false +} + +@@QtQuick.Text { + id: mask + + text: "hi" + font.pointSize: 31 + font.bold: true + + layer.enabled: true // This is important! The component you use as the mask source NEEDS to have this set to true if not a ShaderEffectSource or Image + visible: false +} + +@@QtQuick.Effects.MultiEffect { + anchors.fill: img + source: img + maskSource: mask + maskEnabled: true + maskInverted: false // You can use this to invert the masked area + + // These make the mask edges antialiased (like OpacityMask does) + maskSpreadAtMin: 1 + maskThresholdMin: 0.5 +} +``` From 6f4b997e637ec366e500d5cce345cd3a5d1cb52c Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Wed, 2 Jul 2025 13:51:25 +1000 Subject: [PATCH 2/3] add use as layer effect section to effects guide Also fix up intro --- src/guide/effects.mdx | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/guide/effects.mdx b/src/guide/effects.mdx index 7c4f16a..57f9bd2 100644 --- a/src/guide/effects.mdx +++ b/src/guide/effects.mdx @@ -3,12 +3,12 @@ title: "Graphical Effects" index: 7 --- -Everyone wants effects in their rice right? Well look no further, @@QtQuick.Effects.MultiEffect -is here! +@@QtQuick.Effects.MultiEffect lets you apply multiple visual effects—like blur, shadow, +and color adjustments—in a single, easy-to-use QML component. # Qt 6 MultiEffect -Now how do I use this you ask? Well, this guide provides a few examples for common uses of +Now, how do I use this you ask? Well, this guide provides a few examples for common uses of effects such as drop shadows, colourisation, masks and blurring. First and foremost (and arguably the most commonly used), drop shadows! To create a drop shadow, @@ -220,6 +220,41 @@ For example, the snippet below applies colourisation, shadow and blur: } ``` +### Using MultiEffect as a layer effect + +The @@QtQuick.Effects.MultiEffect component can also be used as a layer effect instead of a +separate visual item. For example, you can replicate the previous using a layer effect: + +> [!NOTE] +> The source component should be visible and have @@QtQuick.Item.layer.enabled set to `true`. +> Additionally, the @@QtQuick.Effects.MultiEffect does not need to have a size or the +> @@QtQuick.Effects.MultiEffect.source property set. + +```qml +@@QtQuick.Image { + id: img + + source: "/path/to/img" + + layer.enabled: true + layer.effect: @@QtQuick.Effects.MultiEffect { + // Apply colourisation + colorization: 1 + colorizationColor: "#abc4d3" + + // Apply shadow + shadowEnabled: true + shadowBlur: 1 + shadowColor: "#000000" + + // Apply blur (`blurMax` also affects shadow) + blurEnabled: true + blur: 1 + blurMax: 32 + } +} +``` + # Migrating from Qt5Compat As of May 26 2025, Qt 5 reached the End of Support state. However, the Qt 5 Core APIs From fd9a1bbad43a5b933d9922efd91cc8dc86b89fa1 Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Thu, 10 Jul 2025 15:06:47 +1000 Subject: [PATCH 3/3] fix effects guide for foxxed review Use layer.effect by default Other sentence/wording changes Fix prop listing --- src/guide/effects.mdx | 362 ++++++++++++++++++------------------------ 1 file changed, 156 insertions(+), 206 deletions(-) diff --git a/src/guide/effects.mdx b/src/guide/effects.mdx index 57f9bd2..ec642d1 100644 --- a/src/guide/effects.mdx +++ b/src/guide/effects.mdx @@ -8,20 +8,15 @@ and color adjustments—in a single, easy-to-use QML component. # Qt 6 MultiEffect -Now, how do I use this you ask? Well, this guide provides a few examples for common uses of -effects such as drop shadows, colourisation, masks and blurring. - -First and foremost (and arguably the most commonly used), drop shadows! To create a drop shadow, -the [QtQuick.Effects](https://doc.qt.io/qt-6/qtquick-effects-qmlmodule.html) module provides -two components that you can use: @@QtQuick.Effects.RectangularShadow and @@QtQuick.Effects.MultiEffect. - -@@QtQuick.Effects.RectangularShadow is much easier to use and more efficient than -@@QtQuick.Effects.MultiEffect, however it can only be used for rectangular shadows (as the name implies). -On the other hand, @@QtQuick.Effects.MultiEffect can used for most common effects, including all of -the previously mentioned effects. +This guide provides a few examples for common uses of effects such as drop shadows, +colourisation, masks and blurring. ### Shadows +To create a drop shadow, the [QtQuick.Effects](https://doc.qt.io/qt-6/qtquick-effects-qmlmodule.html) +module provides two components that you can use: @@QtQuick.Effects.RectangularShadow and +@@QtQuick.Effects.MultiEffect. + The simplest way to create a rectangular drop shadow is with the @@QtQuick.Effects.RectangularShadow component. This component essentially creates a rectangle with blurred edges to act as a shadow. To use this component, you would typically create one below the source component of the shadow. To position @@ -31,81 +26,73 @@ a component beneath another, you can either simply create it before the other co For example: ```qml -@@QtQuick.Rectangle { - id: rect - - implicitWidth: 100 - implicitHeight: 200 - radius: 30 -} - @@QtQuick.Effects.RectangularShadow { anchors.fill: rect // Fill the source rect radius: rect.radius // Have the same rounding as the source rect blur: 15 // The blur/radius of the shadow spread: 2 // The number of pixels from the edges of the rect the shadow extends from color: "#000000" // The colour of the shadow - z: -1 // Visually positions the shadow behind the source rect +} + +@@QtQuick.Rectangle { + id: rect + + implicitWidth: 100 + implicitHeight: 200 + radius: 30 } ``` For more complex shapes, you can use the @@QtQuick.Effects.MultiEffect with the -@@QtQuick.Effects.MultiEffect.shadowEnabled property set to `true`. You can then use the -@@QtQuick.Effects.MultiEffect.shadowBlur, @@QtQuick.Effects.MultiEffect.shadowScale, -@@QtQuick.Effects.MultiEffect.blurMax, @@QtQuick.Effects.MultiEffect.blurMultiplier, -@@QtQuick.Effects.MultiEffect.shadowHorizontalOffset, @@QtQuick.Effects.MultiEffect.shadowVerticalOffset, -@@QtQuick.Effects.MultiEffect.shadowOpacity and @@QtQuick.Effects.MultiEffect.shadowColor properties to -tweak the drop shadow looks to your liking. +@@QtQuick.Effects.MultiEffect.shadowEnabled property set to `true`. You can then modify the +following properties to tweak the drop shadow to your liking: + +- @@QtQuick.Effects.MultiEffect.shadowBlur - A real between 0 and 1 describing the amount of blur +- @@QtQuick.Effects.MultiEffect.shadowScale - Essentially the same as @@QtQuick.Effects.RectangularShadow.spread + but as a multiplier of the source's size +- @@QtQuick.Effects.MultiEffect.blurMax - Affects the radius of the shadow (`radius = blurMax * shadowBlur`) +- @@QtQuick.Effects.MultiEffect.blurMultiplier - A multiplier to apply to the blur +- @@QtQuick.Effects.MultiEffect.shadowHorizontalOffset - Positions the shadow horizontally +- @@QtQuick.Effects.MultiEffect.shadowVerticalOffset - Positions the shadow vertically +- @@QtQuick.Effects.MultiEffect.shadowOpacity - Affects the opacity of the shadow (multiplied with the alpha of + @@QtQuick.Effects.MultiEffect.shadowColor) +- @@QtQuick.Effects.MultiEffect.shadowColor - The colour of the shadow Here's a simple example: -> [!NOTE] -> @@QtQuick.Effects.MultiEffect renders a new visual item alongside the source component, -> meaning displaying the source component as well as the @@QtQuick.Effects.MultiEffect is unecessary -> and wastes CPU cycles. To avoid this, you should either set `visible: false` or `opacity: 0` on -> the source component. The first will prevent it from receiving mouse events while the second won't. - ```qml @@QtQuick.Rectangle { - id: rect - implicitWidth: 100 implicitHeight: 200 radius: 100 - visible: false -} -@@QtQuick.Effects.MultiEffect { - anchors.fill: rect - source: rect - shadowEnabled: true // This must be true for the shadow work - blurMax: 32 // This affects the radius of the shadow (this is also affected by `shadowBlur` and `blurMultiplier`) - shadowScale: 1 // This is essentially the same as `RectangularShadow#spread` but as a multiplier of the source's size - shadowColor: "#000000" // The colour of the shadow + layer.enabled: true // This can be set to false to disable the effect (also unloads the MultiEffect to save memory) + layer.effect: @@QtQuick.Effects.MultiEffect { + shadowEnabled: true // This must be true for the shadow work + blurMax: 32 + shadowScale: 1 + shadowColor: "#000000" + } } ``` ### Simple effects For simple effects like colourisation, brightness, contrast and saturation, @@QtQuick.Effects.MultiEffect -provides them as easily animatable props. +provides them as properties that can be easily animated. ```qml @@QtQuick.Image { - id: img - source: "/path/to/img" - visible: false -} -@@QtQuick.Effects.MultiEffect { - anchors.fill: img - source: img - colorization: 1 // The amount of colourisation as a real between 0 and 1 (0 is no colourisation) - colorizationColor: "#ab35a3" // The colour of the colourisation to apply - brightness: 0.3 // The brightness to apply as a real between -1 and 1 (0 is no change) - contrast: 0.5 // The contrast to apply as a real between -1 and 1 (0 is no change) - saturation: 6 // The saturation to apply as a real greater than -1 (0 is no change) + layer.enabled: true + layer.effect: @@QtQuick.Effects.MultiEffect { + colorization: 1 // The amount of colourisation as a real between 0 and 1 (0 is no colourisation) + colorizationColor: "#ab35a3" // The colour of the colourisation to apply + brightness: 0.3 // The brightness to apply as a real between -1 and 1 (0 is no change) + contrast: 0.5 // The contrast to apply as a real between -1 and 1 (0 is no change) + saturation: 6 // The saturation to apply as a real greater than -1 (0 is no change) + } } ``` @@ -118,22 +105,15 @@ provides them as easily animatable props. > if it is not a @@QtQuick.ShaderEffectSource or texture provider such as @@QtQuick.Image. > > Additionally, the mask source will be scaled to the size of the @@QtQuick.Effects.MultiEffect, -> so you must wrap it in another item for it to be positioned and sized correctly. +> so you must wrap it in another component for it to be positioned and sized correctly. For example: ```qml -@@QtQuick.Image { - id: img - - source: "/path/to/img" - visible: false -} - @@QtQuick.Item { id: mask - visible: false + visible: false // The mask should not be visible if used only as a mask layer.enabled: true @@QtQuick.Rectangle { @@ -143,16 +123,19 @@ For example: } } -@@QtQuick.Effects.MultiEffect { - anchors.fill: img - source: img - maskSource: mask - maskEnabled: true // This must be true for the mask to work - maskInverted: false // You can use this to invert the masked area +@@QtQuick.Image { + source: "/path/to/img" + + layer.enabled: true + layer.effect: @@QtQuick.Effects.MultiEffect { + maskSource: mask + maskEnabled: true // This must be true for the mask to work + maskInverted: false // You can use this to invert the masked area - // These provide antialiasing for the edges of the mask and make it look much better - maskSpreadAtMin: 1 - maskThresholdMin: 0.5 + // These provide antialiasing for the edges of the mask and make it look much better + maskSpreadAtMin: 1 + maskThresholdMin: 0.5 + } } ``` @@ -161,37 +144,75 @@ For example: Blurring is also done using the @@QtQuick.Effects.MultiEffect component. It is done similarly to shadows, however instead of setting the @@QtQuick.Effects.MultiEffect.shadowEnabled property to `true`, you set the @@QtQuick.Effects.MultiEffect.blurEnabled property to `true`. -The blur effect can be customised with the @@QtQuick.Effects.MultiEffect.blur, -@@QtQuick.Effects.MultiEffect.blurMax and @@QtQuick.Effects.MultiEffect.blurMultiplier properties. +The blur effect can be customised with the following properties: + +- @@QtQuick.Effects.MultiEffect.blur - The same as @@QtQuick.Effects.MultiEffect.shadowBlur mentioned above +- @@QtQuick.Effects.MultiEffect.blurMax - The same as mentioned above, except `radius = blurMax * blur` (not `shadowBlur`) +- @@QtQuick.Effects.MultiEffect.blurMultiplier - The same as mentioned above For example: ```qml @@QtQuick.Image { - id: img - source: "/path/to/img" - visible: false -} -@@QtQuick.Effects.MultiEffect { - anchors.fill: img - source: img - blurEnabled: true - blur: 1 // This affects the radius of the blur (a real between 0 and 1) - blurMax: 32 // This affects the max radius of the blur (i.e. the radius when `blur` is 1) - blurMultiplier: 1 // A multiplier for the blur radius (0 is not multiplied) + layer.enabled: true + layer.effect: @@QtQuick.Effects.MultiEffect { + blurEnabled: true + blur: 1 // This affects the radius of the blur (a real between 0 and 1) + blurMax: 32 // This affects the max radius of the blur (i.e. the radius when `blur` is 1) + blurMultiplier: 1 // A multiplier for the blur radius (0 is not multiplied) + } } ``` ### Stacking effects -The advantage of using a @@QtQuick.Effects.MultiEffect is that you can apply multiple effects -to a component in a single pass. You can do this by simply setting that effect's corresponding enabled +A useful feature of @@QtQuick.Effects.MultiEffect is that you can apply multiple effects to a +component in a single pass. You can do this by simply setting that effect's corresponding enabled property to `true` and configuring it as shown previously. For example, the snippet below applies colourisation, shadow and blur: +```qml +@@QtQuick.Image { + source: "/path/to/img" + + layer.enabled: true + layer.effect: @@QtQuick.Effects.MultiEffect { + // Apply colourisation + colorization: 1 + colorizationColor: "#abc4d3" + + // Apply shadow + shadowEnabled: true + shadowBlur: 1 + shadowColor: "#000000" + + // Apply blur (`blurMax` also affects shadow) + blurEnabled: true + blur: 1 + blurMax: 32 + } +} +``` + +### Using MultiEffect as a separate component + +The @@QtQuick.Effects.MultiEffect component can also be used as a separate visual item instead of a +layer effect. This is useful for more complex effects when you need to manually position/size the +@@QtQuick.Effects.MultiEffect instead having the same position/size as the source component (which is +the case when using it as a layer effect). + +For example, you can replicate the previous example using the @@QtQuick.Effects.MultiEffect as a separate +component: + +> [!NOTE] +> @@QtQuick.Effects.MultiEffect renders a new visual item alongside the source component when not used +> as a layer effect, meaning displaying the source component as well as the @@QtQuick.Effects.MultiEffect +> is unecessary and wastes CPU cycles. To avoid this, you should either set `visible: false` or `opacity: 0` +> on the source component. The first will prevent it from receiving mouse events while the second won't. + ```qml @@QtQuick.Image { id: img @@ -220,41 +241,6 @@ For example, the snippet below applies colourisation, shadow and blur: } ``` -### Using MultiEffect as a layer effect - -The @@QtQuick.Effects.MultiEffect component can also be used as a layer effect instead of a -separate visual item. For example, you can replicate the previous using a layer effect: - -> [!NOTE] -> The source component should be visible and have @@QtQuick.Item.layer.enabled set to `true`. -> Additionally, the @@QtQuick.Effects.MultiEffect does not need to have a size or the -> @@QtQuick.Effects.MultiEffect.source property set. - -```qml -@@QtQuick.Image { - id: img - - source: "/path/to/img" - - layer.enabled: true - layer.effect: @@QtQuick.Effects.MultiEffect { - // Apply colourisation - colorization: 1 - colorizationColor: "#abc4d3" - - // Apply shadow - shadowEnabled: true - shadowBlur: 1 - shadowColor: "#000000" - - // Apply blur (`blurMax` also affects shadow) - blurEnabled: true - blur: 1 - blurMax: 32 - } -} -``` - # Migrating from Qt5Compat As of May 26 2025, Qt 5 reached the End of Support state. However, the Qt 5 Core APIs @@ -312,25 +298,17 @@ For other shapes, you must use a @@QtQuick.Effects.MultiEffect instead. For example, using a @@Qt5Compat.GraphicalEffects.DropShadow: ```qml -// Note that the source component should not be visible when using DropShadow -// as DropShadow renders a new visual item alongside the source component, -// meaning displaying the source component as well as the DropShadow is unecessary -// and wastes CPU cycles rendering the source component. @@QtQuick.Rectangle { - id: rect - implicitWidth: 100 implicitHeight: 200 radius: 30 - visible: false -} -@@Qt5Compat.GraphicalEffects.DropShadow { - anchors.fill: rect - source: rect - radius: 8 - samples: 1 + radius * 2 - color: "#000000" + layer.enabled: true + layer.effect: @@Qt5Compat.GraphicalEffects.DropShadow { + radius: 8 + samples: 1 + radius * 2 + color: "#000000" + } } ``` @@ -338,22 +316,18 @@ You can replicate this using a @@QtQuick.Effects.RectangularShadow or a @@QtQuic You should use @@QtQuick.Effects.RectangularShadow over @@QtQuick.Effects.MultiEffect when you are able to as they are easier to use and more efficient. -Using a @@QtQuick.Effects.RectangularShadow: +A (relatively) equivalent example to the previous @@Qt5Compat.GraphicalEffects.DropShadow example +using a @@QtQuick.Effects.RectangularShadow: ```qml -// Note that the RectangularShadow is below the source component of the shadow. -// You can do this either by putting it before the source (like so) -// or by setting the `z` property to less than the source's. @@QtQuick.Effects.RectangularShadow { anchors.fill: rect - radius: rect.radius // Affects the radius of the rectangle - blur: 6 // Affects the blur/radius of the shadow - spread: 1 // Affects the scale/spread of the shadow from the edges of the rectangle in pixels + radius: rect.radius + blur: 6 + spread: 1 color: "#000000" } -// Also note that the actual component should be visible when using a RectangularShadow -// as the shadow is solely a shadow, unlike a MultiEffect. @@QtQuick.Rectangle { id: rect @@ -363,28 +337,21 @@ Using a @@QtQuick.Effects.RectangularShadow: } ``` -Using a @@QtQuick.Effects.MultiEffect: +Also (relatively) equivalent, using a @@QtQuick.Effects.MultiEffect: ```qml -// Note that the source component should not be visible for the same reason as -// the DropShadow. This applies to all uses of MultiEffect. @@QtQuick.Rectangle { - id: rect - implicitWidth: 100 implicitHeight: 200 radius: 30 - visible: false -} -@@QtQuick.Effects.MultiEffect { - anchors.fill: rect - source: rect - shadowEnabled: true // This must be true for the shadow work - blurMax: 32 // This affects the radius of the shadow (this is also affected by `shadowBlur` and `blurMultiplier`) - shadowBlur: 0.5 - shadowScale: 1 // This is essentially the same as `RectangularShadow#spread` but as a multiplier of the source's size - shadowColor: "#000000" + layer.enabled: true + layer.effect: @@QtQuick.Effects.MultiEffect { + shadowEnabled: true + blurMax: 32 + shadowBlur: 0.5 + shadowColor: "#000000" + } } ``` @@ -400,16 +367,12 @@ Using a @@Qt5Compat.GraphicalEffects.FastBlur: ```qml @@QtQuick.Image { - id: img - source: "path/to/image" - visible: false -} -@@Qt5Compat.GraphicalEffects.FastBlur { - anchors.fill: img - source: img - radius: 32 + layer.enabled: true + layer.effect: @@Qt5Compat.GraphicalEffects.FastBlur { + radius: 32 + } } ``` @@ -417,18 +380,14 @@ Using a @@QtQuick.Effects.MultiEffect: ```qml @@QtQuick.Image { - id: img - source: "path/to/image" - visible: false -} -@@QtQuick.Effects.MultiEffect { - anchors.fill: img - source: img - blurEnabled: true // This must be true for the blur to work - blur: 1 // Affects the amount of blur - blurMax: 34 // Affects the max radius of the blur (i.e. the radius of the blur when `blur` is 1) + layer.enabled: true + layer.effect: @@QtQuick.Effects.MultiEffect { + blurEnabled: true + blur: 1 + blurMax: 34 + } } ``` @@ -440,13 +399,6 @@ should use a @@QtQuick.Effects.MultiEffect with the @@QtQuick.Effects.MultiEffec Using an @@Qt5Compat.GraphicalEffects.OpacityMask: ```qml -@@QtQuick.Image { - id: img - - source: "path/to/image" - visible: false -} - @@QtQuick.Text { id: mask @@ -456,10 +408,13 @@ Using an @@Qt5Compat.GraphicalEffects.OpacityMask: visible: false } -@@Qt5Compat.GraphicalEffects.OpacityMask { - anchors.fill: img - source: img - maskSource: mask +@@QtQuick.Image { + source: "path/to/image" + + layer.enabled: true + layer.effect: @@Qt5Compat.GraphicalEffects.OpacityMask { + maskSource: mask + } } ``` @@ -467,10 +422,17 @@ Using a @@QtQuick.Effects.MultiEffect: ```qml @@QtQuick.Image { - id: img - source: "path/to/image" - visible: false + + layer.enabled: true + layer.effect: @@QtQuick.Effects.MultiEffect { + maskSource: mask + maskEnabled: true + + // These make the mask edges antialiased (like OpacityMask does) + maskSpreadAtMin: 1 + maskThresholdMin: 0.5 + } } @@QtQuick.Text { @@ -483,16 +445,4 @@ Using a @@QtQuick.Effects.MultiEffect: layer.enabled: true // This is important! The component you use as the mask source NEEDS to have this set to true if not a ShaderEffectSource or Image visible: false } - -@@QtQuick.Effects.MultiEffect { - anchors.fill: img - source: img - maskSource: mask - maskEnabled: true - maskInverted: false // You can use this to invert the masked area - - // These make the mask edges antialiased (like OpacityMask does) - maskSpreadAtMin: 1 - maskThresholdMin: 0.5 -} ```