How to apply a custom style to a custom component
-
Hello QML gurus!
I'm currently developing a user interface that is designed by a UX/UI specialist. This UI would be available in both a light and a dark mode. Since none of the existing Control styles provide the look I need (at least the ones listed here), I created my own dark and light styles following the tutorials scattered over the internet. This works a treat for all the standard components listed on the page Qt Quick Templates 2 QML Types. Awesome!
However, since my custom UI does contain some custom controls, I really can't figure out how to stylize my custom component based on these different styles.
For example, On the bottom of the application I have a button bar with 3 buttons, between the button bar and the content above it, there is a divider line. This line should be white in dark mode and black in light mode. I currently have: (removed most of the layouting to reduce the size):
// file ButtonBar.qml import QtQuick 6.2 //... Item { ColumnLayout { Rectangle { id: divider color: "#000000" height: 1 } Pane { id: pane RowLayout { spacing: 15 Button { id: button1 text: qsTr("HOME") icon.source: "../icons/png/home.png" } Button { id: button2 text: qsTr("TRACK") icon.source: "../icons/png/track.png" } Button { id: button3 text: qsTr("MORE") icon.source: "../icons/png/kebab.png" } } } } }
As you can see, the divider is just a 1 pixel tall Rectangle, right now hardcoded to black. How can I change the color of this divider automatically based on the chosen style? I was able to work around this for now (but it feels a bit 'hacky') by adding some custom properties to the
Pane
and accessing those in theButtonBar
component:// file: light/Pane.qml import QtQuick import QtQuick.Templates 6.2 as T T.Pane { id: control property color foregroundColor: "#000000" property color backgroundColor: "#f0f0f0" background: Rectangle { anchors.fill: parent color: backgroundColor } }
and:
// file: ButtonBar.qml // ... Item { ColumnLayout { Rectangle { id: divider color: pane.foregoundColor height: 1 } Pane { id: pane } } } // ...
Trouble is that I don't always have a pane handy to steal these properties from and I also don't feel like adding these to every template.
I know this must be possible somehow, I just can't wrap my head around this right now. All help is appreciated!
Cheers,
Nic. -
Well...I knew I was overlooking something. I wasn't exactly approaching this from the right angle. Seems that dark/light modes are more of a 'theme' than a 'style'. Other people trying to do something similar should really read this, it's all there: https://luxoft.github.io/qml-coreui/topics/styles/
I've been developing Qt apps for over 10 years now, but switching to QtQuick makes me a n00b again :)
In short, I created a singleton QtObject that holds the currently selected theme and use this as an import in all my code:
// file: Theme.qml pragma Singleton import QtQuick 6.2 QtObject { readonly property int lightTheme: 0 readonly property int darkTheme: 1 property int theme: darkTheme readonly property color backgroundColor: theme === lightTheme ? "#F0F0F0" : "#000000" readonly property color foregroundColor: theme === darkTheme ? "#F0F0F0" : "#101010" readonly property string backgroundImage: theme === lightTheme ? "../icons/png/background_light.png" : "../icons/png/background_dark.png" }
And in other qml files I do this:
import Theme Rectangle { color: Theme.backgroundColor }