aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@qt.io>2026-06-29 10:08:56 +0200
committerRichard Moe Gustavsen <richard.gustavsen@qt.io>2026-07-02 21:14:15 +0000
commit6ab636db4082235297fdac67fc998514b6cf8e92 (patch)
treef5e3716c81a04b70435b095db796eff86129328a /examples
parent6188f4b0f502e201dd1dab0f6b793c05f4c15568 (diff)
StyleKitExample: remove dependency to Qt Shader Tools
As it stood, the example would use ShaderEffects to demonstrate the use of advanced custom delegates in StyleKit. However, this came with the price that you would need to install the optional Qt Shader Effects module in order to build and run the example. This patch will remove the usage of ShaderEffects in this example, so that it works out-of-the-box with a standard installation of Qt. The usage of custom delegates and shader effects will be added to a separate example in a later patch instead. Pick-to: 6.12 Change-Id: Icc4bdfe92d02b465666dcde21695cec6caf65313 Reviewed-by: Dilek Akcay <dilek.akcay@qt.io> Reviewed-by: Doris Verria <doris.verria@qt.io>
Diffstat (limited to 'examples')
-rw-r--r--examples/stylekit/stylekitcontrols/CMakeLists.txt49
-rw-r--r--examples/stylekit/stylekitcontrols/Main.qml2
-rw-r--r--examples/stylekit/stylekitcontrols/doc/src/qtlabsstylekit-example.qdoc7
-rw-r--r--examples/stylekit/stylekitcontrols/noise.frag48
-rw-r--r--examples/stylekit/stylekitcontrols/qt.pngbin3118 -> 0 bytes
-rw-r--r--examples/stylekit/stylekitcontrols/styles/CustomDelegates.qml348
-rw-r--r--examples/stylekit/stylekitcontrols/styles/Vitrum.qml48
-rw-r--r--examples/stylekit/stylekitcontrols/wave.frag23
8 files changed, 1 insertions, 524 deletions
diff --git a/examples/stylekit/stylekitcontrols/CMakeLists.txt b/examples/stylekit/stylekitcontrols/CMakeLists.txt
index ab08954791..f23b4f53e3 100644
--- a/examples/stylekit/stylekitcontrols/CMakeLists.txt
+++ b/examples/stylekit/stylekitcontrols/CMakeLists.txt
@@ -5,11 +5,6 @@ cmake_minimum_required(VERSION 3.16)
project(StyleKitControlsExample VERSION 1.0 LANGUAGES CXX)
find_package(Qt6 6.11 REQUIRED COMPONENTS Core Gui Qml Quick QuickControls2)
-find_package(Qt6 6.11 COMPONENTS ShaderTools)
-
-if(NOT TARGET Qt::qsb)
- message(FATAL_ERROR "qsb not found. Please install Qt Shader Tools to build this example.")
-endif()
qt_standard_project_setup(REQUIRES 6.11)
@@ -17,7 +12,6 @@ set(STYLES
styles/Plain.qml
styles/Haze.qml
styles/Vitrum.qml
- styles/CustomDelegates.qml
styles/Fusion.qml
)
@@ -32,49 +26,6 @@ qt_add_qml_module(${PROJECT_NAME}
${STYLES}
)
-qt_add_resources(${PROJECT_NAME} "images"
- PREFIX "/images"
- FILES
- qt.png
-)
-
-qt_add_resources(${PROJECT_NAME} "effects"
- PREFIX "/effects"
- FILES
- wave.frag wave.qsb
- noise.frag noise.qsb
-)
-
-set(SHADERS
- wave.frag
- noise.frag
-)
-
-set(QSB_FLAGS
- --glsl 460,450,320es
- --hlsl 50
- --msl 12
- --msl 20
-)
-
-set(GENERATED_SHADERS)
-foreach(SHADER ${SHADERS})
- get_filename_component(NAME_WE ${SHADER} NAME_WE)
- set(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/${NAME_WE}.qsb)
-
- add_custom_command(
- OUTPUT ${OUTPUT}
- COMMAND "$<TARGET_FILE:Qt::qsb>" ${QSB_FLAGS} -o ${OUTPUT} ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER}
- DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER}
- COMMENT "Compiling shader ${SHADER} → ${NAME_WE}.qsb"
- VERBATIM
- )
- list(APPEND GENERATED_SHADERS ${OUTPUT})
-endforeach()
-
-add_custom_target(shaders ALL DEPENDS ${GENERATED_SHADERS})
-add_dependencies(${PROJECT_NAME} shaders)
-
target_link_libraries(${PROJECT_NAME}
PRIVATE
Qt6::Quick
diff --git a/examples/stylekit/stylekitcontrols/Main.qml b/examples/stylekit/stylekitcontrols/Main.qml
index 82f23b7939..83975ce81f 100644
--- a/examples/stylekit/stylekitcontrols/Main.qml
+++ b/examples/stylekit/stylekitcontrols/Main.qml
@@ -20,7 +20,6 @@ ApplicationWindow {
// at runtime, and each style provides its own set of themes.
Haze { id: hazeStyle }
Vitrum { id: vitrumStyle }
- CustomDelegates { id: delegateStyle }
Plain { id: plainStyle }
Fusion { id: fusionStyle }
@@ -318,7 +317,6 @@ ApplicationWindow {
{ value: hazeStyle, text: "Haze" },
{ value: plainStyle, text: "Plain" },
{ value: vitrumStyle, text: "Vitrum" },
- { value: delegateStyle, text: "CustomDelegates" },
{ value: fusionStyle, text: "Fusion" }
]
onCurrentTextChanged: {
diff --git a/examples/stylekit/stylekitcontrols/doc/src/qtlabsstylekit-example.qdoc b/examples/stylekit/stylekitcontrols/doc/src/qtlabsstylekit-example.qdoc
index 16c0b9e9db..0fc8651d97 100644
--- a/examples/stylekit/stylekitcontrols/doc/src/qtlabsstylekit-example.qdoc
+++ b/examples/stylekit/stylekitcontrols/doc/src/qtlabsstylekit-example.qdoc
@@ -18,7 +18,7 @@
\li \b Plain - A minimal style with only the basics
\li \b Haze - An advanced style with multiple themes
\li \b Vitrum - A style targeting VR environments
- \li \b CustomDelegates - A style demonstrating how to create overlays, underlays, and shader effects
+ \li \b Fusion - A classical desktop Fusion style
\endlist
The example demonstrates, among other things, how to:
@@ -29,8 +29,6 @@
such as high-contrast.
\li Use \l StyleVariation to provide alternative styling for
parts of the application.
- \li Implement custom delegates to add overlay and underlay effects.
- \li Apply shader-based visual effects to the controls.
\li Build custom controls using \l CustomControl and \l StyleReader.
\li Interact with a style at runtime, for example to change the
theme or adjust style properties like the background radius.
@@ -39,7 +37,4 @@
\sa {Qt Labs StyleKit}, Style, Theme
\include examples-run.qdocinc
-
- \note This example requires Qt Shader Tools, an optional library available
- through the Qt Maintenance Tool.
*/
diff --git a/examples/stylekit/stylekitcontrols/noise.frag b/examples/stylekit/stylekitcontrols/noise.frag
deleted file mode 100644
index 019ec50057..0000000000
--- a/examples/stylekit/stylekitcontrols/noise.frag
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (C) 2025 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#version 440
-precision highp float;
-
-layout(location = 0) in vec2 qt_TexCoord0;
-layout(location = 0) out vec4 fragColor;
-
-layout(binding = 1) uniform sampler2D source;
-
-layout(std140, binding = 0) uniform buf {
- mat4 qt_Matrix; // reserved
- float qt_Opacity; // reserved
- vec2 sourceItemSize; // The size of the input item. The source is divided into a grid of cells.
- vec4 borderColor; // The color of the border (to be masked away). Set to transparent to ignore.
- vec4 particleColor; // The color of the noise particle
- float borderMaskEnabled; // Enabled mask or not. If the bg and border color is the same, set this to 0
- float borderMaskThreshold; // The threshold for determining if a pixel belongs to the border (taking anti-aliasing into account)
- float particleSize; // The size of a dust particle (aka the cell size in the grid)
- float particleOpacity; // The particleOpacity of the particle
- float particleDensity; // The threshold deciding if a particle (aka cell in the grid) should be visible or not
- float time; // time, for animating the noise
-} args;
-
-float random(vec2 st, float t) {
- vec2 offsetSt = st + t;
- return fract(sin(dot(offsetSt.xy, vec2(12.9898, 78.233))) * 43758.5453123);
-}
-
-void main() {
- vec4 sourceColor = texture(source, qt_TexCoord0);
- vec2 pixelCoord = qt_TexCoord0 * args.sourceItemSize;
- vec2 noiseCoord = floor(pixelCoord / args.particleSize);
- float randomValue = random(noiseCoord, args.time);
- float noiseMix = step(randomValue, args.particleDensity);
-
- float calculatedBorderMask = step(args.borderMaskThreshold, distance(sourceColor.rgba, args.borderColor.rgba));
- float borderMask = mix(1.0, calculatedBorderMask, args.borderMaskEnabled);
- float finalMask = sourceColor.a * borderMask;
- float finalAlpha = sourceColor.a * args.qt_Opacity;
- float maskedNoiseAlpha = noiseMix * args.particleOpacity * finalMask;
-
- vec3 blendedColor = mix(sourceColor.rgb, args.particleColor.rgb, maskedNoiseAlpha);
- vec3 preMultipliedColor = blendedColor * args.qt_Opacity;
-
- fragColor = vec4(preMultipliedColor, finalAlpha);
-}
diff --git a/examples/stylekit/stylekitcontrols/qt.png b/examples/stylekit/stylekitcontrols/qt.png
deleted file mode 100644
index a7b16ba4f9..0000000000
--- a/examples/stylekit/stylekitcontrols/qt.png
+++ /dev/null
Binary files differ
diff --git a/examples/stylekit/stylekitcontrols/styles/CustomDelegates.qml b/examples/stylekit/stylekitcontrols/styles/CustomDelegates.qml
deleted file mode 100644
index 3c2eabed5e..0000000000
--- a/examples/stylekit/stylekitcontrols/styles/CustomDelegates.qml
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright (C) 2025 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-import QtQuick
-import QtQuick.Shapes
-import QtQuick.Templates as T
-import Qt.labs.StyleKit
-
-Style {
-
- /******************************************************************
- * Defining some helper types for the custom delegates further down
- ******************************************************************/
-
- component Star : Shape {
- id: star
- ShapePath {
- fillColor: star.palette.accent
- scale: Qt.size(star.width, star.height)
- PathMove { x: 0.50; y: 0.00 }
- PathLine { x: 0.59; y: 0.35 }
- PathLine { x: 0.97; y: 0.35 }
- PathLine { x: 0.66; y: 0.57 }
- PathLine { x: 0.78; y: 0.91 }
- PathLine { x: 0.50; y: 0.70 }
- PathLine { x: 0.22; y: 0.91 }
- PathLine { x: 0.34; y: 0.57 }
- PathLine { x: 0.03; y: 0.35 }
- PathLine { x: 0.41; y: 0.35 }
- PathLine { x: 0.50; y: 0.00 }
- }
- NumberAnimation on rotation {
- loops: Animation.Infinite
- from: 0
- to: 359
- duration: 20000
- }
- }
-
- component OverlayData: QtObject {
- property real overlayScale: 1
- }
-
- /******************************************************************
- * Define custom delegates. These replace the default StyledItem
- * for selected controls in the style definition below.
- ******************************************************************/
-
- component OverlayDelegate : StyledItem {
- /* Using StyledItem as the base type is the easiest approach when creating
- * a custom delegate. A StyledItem will draw the delegate as configured by
- * the style, and give you the opportunity to place your own items on top. */
- id: delegate
- width: parent.width
- height: parent.height
-
- Star {
- width: 40
- height: 40
- anchors.centerIn: parent
- anchors.verticalCenterOffset: -10
- scale: delegate.delegateStyle.data.overlayScale
- Behavior on scale {
- NumberAnimation {
- duration: 300
- easing.type: Easing.OutBounce
- }
- }
- }
- Text {
- text: "overlay"
- font.pixelSize: 8
- y: -10
- }
- }
-
- component UnderlayDelegate : Item {
- /* Custom delegates that don't inherit from StyledItem needs to define
- * 'delegateStyle' and 'control' properties, which are assinged to by StyleKit.
- * Use 'delegateStyle' to bind to style attributes like color, radius, and opacity.
- * Use 'control' to access the Quick Control the owns the delegate. */
- id: delegate
- required property DelegateStyle delegateStyle
- required property QtObject control
-
- implicitWidth: delegateStyle.width
- implicitHeight: delegateStyle.height
- width: parent.width
- height: parent.height
-
- Star {
- visible: delegate.control.checked
- anchors.centerIn: parent
- anchors.verticalCenterOffset: -1
- width: 60
- height: 60
- }
-
- Text {
- text: "underlay"
- font.pixelSize: 8
- y: -10
- }
-
- StyledItem {
- // Embed a StyledItem to render the standard delegate on top
- delegateStyle: delegate.delegateStyle
- }
- }
-
- component SliderHandle : StyledItem {
- /* Unlike the 'data' property, which varies per state, you can use regular
- * QML properties to pass static information to a delegate. Here, 'isFirstHandle'
- * distinguishes the first from the second handle in a RangeSlider, and
- * 'control' gives access to the slider's current value(s). */
- id: sliderHandle
- property bool isFirstHandle: false
- required property QtObject control
-
- Text {
- color: "ghostwhite"
- anchors.centerIn: parent
- font.pixelSize: 9
- text: {
- if (sliderHandle.control instanceof T.RangeSlider) {
- if (sliderHandle.isFirstHandle)
- return sliderHandle.control.first.value.toFixed(0)
- else
- return sliderHandle.control.second.value.toFixed(0)
- }
-
- return sliderHandle.control.value.toFixed(0)
- }
- }
- }
-
- component NoiseDelegate : ShaderEffect {
- /* Use graphical effects in combination with StyledItem to create more
- * complex delegate appearances. In this delegate, we create a noise overlay. */
- implicitWidth: unifiedSourceItem.implicitWidth
- implicitHeight: unifiedSourceItem.implicitHeight
- width: parent.width
- height: parent.height
-
- required property DelegateStyle delegateStyle
-
- // The following properties are used by the shader (noise.frag)
- property size sourceItemSize: Qt.size(unifiedSourceItem.width, unifiedSourceItem.height)
- property color borderColor: delegateStyle.border.color
- property real borderMaskEnabled: 1
- property real borderMaskThreshold: 0.001
- property real particleDensity: 0.1
- property real particleSize: 1
- property color particleColor: "black"
- property Item source: ShaderEffectSource { live: true; sourceItem: unifiedSourceItem }
- property real particleOpacity: 0.4
- property real time
-
- // Note: noise.frag is compiled to noise.qsb from CMakeLists.txt
- fragmentShader: "qrc:/effects/noise.qsb"
-
- NumberAnimation on time {
- loops: Animation.Infinite
- from: 0
- to: Math.PI * 2
- duration: 1000
- }
-
- StyledItem {
- id: unifiedSourceItem
- delegateStyle: parent.delegateStyle
- width: parent.width
- height: parent.height
- visible: false
- rotation: 0.0
- scale: 1.0
- }
-
- Text {
- text: "noise"
- font.pixelSize: 8
- y: -10
- }
- }
-
- component WavingQt : ShaderEffect {
- implicitWidth: delegateStyle.width
- implicitHeight: delegateStyle.height
- visible: delegateStyle.visible
-
- required property DelegateStyle delegateStyle
-
- // The following properties are used by the shader (wave.frag)
- property real amplitude: 0.04 * 0.5
- property real frequency: 20
- property real time
-
- NumberAnimation on time {
- loops: Animation.Infinite
- from: 0
- to: Math.PI * 2
- duration: 600
- }
-
- // Note: wave.frag is compiled to wave.qsb from CMakeLists.txt
- fragmentShader: "qrc:/effects/wave.qsb"
-
- property Item sourceItem: ShaderEffectSource {
- sourceItem: Image {
- width: 40
- height: 40
- source: "qrc:/images/qt.png"
- visible: false
- }
- }
- }
-
- component CustomShadowDelegate : Item {
- required property DelegateStyle delegateStyle
-
- x: delegateStyle.shadow.verticalOffset
- y: delegateStyle.shadow.horizontalOffset
- width: parent.width
- height: parent.height
-
- Rectangle {
- width: parent.width
- height: parent.height
- radius: parent.delegateStyle.radius
- color: parent.delegateStyle.shadow.color
- opacity: parent.delegateStyle.shadow.opacity
- }
-
- Text {
- anchors.right: parent.right
- anchors.top: parent.bottom
- anchors.rightMargin: 10
- font.pixelSize: 8
- text: "Custom shadow"
- }
- }
-
- /******************************************************************
- * Define the style, assigning the custom delegates above to specific
- * controls in place of the default StyledItem:
- ******************************************************************/
-
- applicationWindow {
- background.color: "#544e52"
- }
-
- control {
- text.color: "ghostwhite"
- background {
- border.color: "#3d373b"
- shadow.color: "#555555"
- color: "#8e848a"
- }
-
- handle {
- color: "#8e848a"
- border.color: Qt.darker("#544e52", 1.5)
- shadow.color: "#808080"
- }
-
- indicator {
- color: Qt.darker("#8e848a", 1.6)
- }
- }
-
- button {
- topPadding: 30
- background {
- delegate: OverlayDelegate{}
- // Use the 'data' property to pass custom, per-state information to a custom delegate
- data: OverlayData {
- overlayScale: 0.5
- }
- }
- hovered.background.color: Qt.lighter("#8e848a", 1.2)
- hovered.background.data: OverlayData {
- overlayScale: 1.8
- }
- pressed.background.data: OverlayData {
- overlayScale: 1.6
- }
- checked.background.data: OverlayData {
- overlayScale: 1.4
- }
- }
-
- flatButton {
- background.shadow.visible: false
- }
-
- checkBox {
- indicator.foreground {
- width: 30
- height: 30
- margins: 4
- delegate: WavingQt {}
- }
- }
-
- menuBarItem {
- hovered.background.color: Qt.lighter("#8e848a", 1.2)
- }
-
- menuItem {
- hovered.background.color: Qt.lighter("#8e848a", 1.2)
- }
-
- radioButton {
- indicator.delegate: UnderlayDelegate {}
- }
-
- slider {
- background.visible: true
- // background.delegate: NoiseDelegate {}
- // indicator.delegate: NoiseDelegate {}
- handle.delegate: SliderHandle { isFirstHandle: true }
- handle.second.delegate: SliderHandle { isFirstHandle: false }
- }
-
- textField {
- background.shadow.verticalOffset: 4
- background.shadow.horizontalOffset: 4
- background.shadow.delegate: CustomShadowDelegate {}
- }
-
- switchControl {
- background.visible: true
- checked {
- background.delegate: NoiseDelegate {}
- indicator.foreground.delegate: NoiseDelegate {}
- }
- }
-
- comboBox {
- background.width: 200
- }
-
- frame {
- padding: 20
- spacing: 50
- hovered.background.color: "#8e848a"
- }
-}
diff --git a/examples/stylekit/stylekitcontrols/styles/Vitrum.qml b/examples/stylekit/stylekitcontrols/styles/Vitrum.qml
index f665e813fc..f9f40b0e55 100644
--- a/examples/stylekit/stylekitcontrols/styles/Vitrum.qml
+++ b/examples/stylekit/stylekitcontrols/styles/Vitrum.qml
@@ -7,46 +7,6 @@ import Qt.labs.StyleKit
Style {
id: style
- component NoiseDelegate : ShaderEffect {
- id: noiseDelegate
- implicitWidth: unifiedSourceItem.implicitWidth
- implicitHeight: unifiedSourceItem.implicitHeight
- width: parent.width
- height: parent.height
-
- required property DelegateStyle delegateStyle
-
- readonly property bool isDarkBg: {
- let bgColor = delegateStyle.color
- let luminance = (0.2126 * bgColor.r) + (0.7152 * bgColor.g) + (0.0722 * bgColor.b);
- return luminance < 0.5;
- }
-
- // The following properties are used by the shader
- property size sourceItemSize: Qt.size(unifiedSourceItem.width, unifiedSourceItem.height)
- property color borderColor: delegateStyle.border.color
- property real borderMaskEnabled: 1
- property real borderMaskThreshold: 0.001
- property real particleDensity: 0.2
- property real particleSize: 0.5
- property color particleColor: "black"
- property Item source: ShaderEffectSource { live: true; sourceItem: unifiedSourceItem }
- property real time: 0
- property real particleOpacity: (delegateStyle.opacity === 1
- ? (isDarkBg ? 0.15 : 0.05)
- : (isDarkBg ? 0.5 : 0.1))
-
- fragmentShader: "qrc:/effects/noise.qsb"
-
- StyledItem {
- id: unifiedSourceItem
- delegateStyle: noiseDelegate.delegateStyle
- width: parent.width
- height: parent.height
- visible: false
- }
- }
-
component ColorSet : QtObject {
property color normal
property color muted
@@ -126,7 +86,6 @@ Style {
background {
height: myTheme.controlHeight
color: myTheme.neutralBackground.normal
- delegate: NoiseDelegate {}
}
vertical {
@@ -141,7 +100,6 @@ Style {
border.width: 2
border.color: myTheme.neutralStroke.normal
color: myTheme.accentForeground.normal
- delegate: NoiseDelegate {}
}
indicator {
@@ -150,7 +108,6 @@ Style {
border.width: 3
border.color: myTheme.neutralStroke.normal
color: myTheme.neutralBackground.normal
- delegate: NoiseDelegate {}
foreground {
radius: 25
gradient: strongVerticalGradient
@@ -173,7 +130,6 @@ Style {
border.color: myTheme.neutralStroke.normal
color: myTheme.neutralBackground.normal
gradient: faintVerticalGradient
- delegate: NoiseDelegate {}
shadow {
opacity: 0.25
@@ -185,10 +141,6 @@ Style {
}
}
- indicator {
- foreground.delegate: NoiseDelegate {}
- }
-
hovered {
background.color: myTheme.neutralBackground.muted
checked.background.color: myTheme.accentBackground.muted
diff --git a/examples/stylekit/stylekitcontrols/wave.frag b/examples/stylekit/stylekitcontrols/wave.frag
deleted file mode 100644
index b8284974e7..0000000000
--- a/examples/stylekit/stylekitcontrols/wave.frag
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (C) 2025 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#version 440
-
-layout(location = 0) in vec2 qt_TexCoord0;
-layout(location = 0) out vec4 fragColor;
-
-layout(binding = 1) uniform sampler2D sourceItem;
-
-layout(std140, binding = 0) uniform buf {
- mat4 qt_Matrix; // reserved
- float qt_Opacity; // reserved
- float amplitude;
- float frequency;
- float time;
-} args;
-
-void main()
-{
- vec2 p = sin(args.time + args.frequency * qt_TexCoord0);
- fragColor = texture(sourceItem, qt_TexCoord0 + args.amplitude * vec2(p.y, -p.x)) * args.qt_Opacity;
-}