I'm trying to make a QtQuick app with color themes. I plan to make a few .qml style sheets that define concepts like buttonColor, fontColor and so on. Here's an example of what the style sheets will look like more or less:
pragma Singleton
import QtQuick
QtObject {
property color bodyTextColor: "white"
property color headerTextColor: "black"
property int buttonBorderWidth: 3
property color buttonColor: "#007bff"
property color backgroundColor: "#000000"
property color accentColor: "#6c757d"
property int fontSize: 16
property int titleFontSize: fontSize + 8
property int labelFontSize: fontSize - 16
}
I tried import "ClassicStylesheet.qml" as Styles
and it can't find it even though it's in the same root directory with Main.qml (I get a "no such directory" error). Using an absolute path to ClassicStylesheet.qml gets around this and the app runs, but it still doesn't work. I get the following error:
Could not find any constructor for value type QQuickColorValueType to call with value QVariant(QObject*, 0x0) qrc:/[projectname]/Main.qml:31:17: Unable to assign undefined to QColor
All components render in black when running with an absolute path to the style sheet. Here's an example of my Main.qml file using my reusable LargeButton component (which renders fine using defaults, without the stylesheet) to create a main menu button:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import "ClassicStylesheet.qml" as Styles
Window {
width: 1280
height: 720
visible: true
title: qsTr("Test")
Rectangle {
id: menuFrame
width: 600
height: 400
color: "lightgrey"
anchors.centerIn: parent
radius: 25
ColumnLayout {
anchors.centerIn: parent
spacing: 10
LargeButton {
text: "Settings"
buttonColor: Styles.buttonColor
accentColor: Styles.accentColor
fontColor: Styles.fontColor
onClicked:
{
}
}
}
}
}
Any advice on navigating this? Why doesn't it recognize my file or read its contents? Thanks.
There's no need to import a singleton file. You might need to supply a qmldir
file.
singleton AppThemes 1.0 AppThemes.qml
In the following demo, there are two themes. A "light" and "dark" theme. These are available via the AppThemes
singleton. The standard Palette
format is used so that it can be assigned at a top-level component and it will be inherited by all controls underneath. Additional parameters, such as fontSize
may be added.
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
title: "AppThemes Demo"
palette: AppThemes.current.palette
ColumnLayout {
RowLayout {
AppButton { text: "File" }
AppButton { text: "Edit" }
AppButton { text: "Settings" }
AppButton { text: "Help" }
}
AppLabel { text: "Pick a Theme" }
Repeater {
model: AppThemes.themes
AppButton {
text: modelData
checked: modelData === AppThemes.currentName
onClicked: AppThemes.currentName = modelData
}
}
}
}
// qmldir
singleton AppThemes 1.0 AppThemes.qml
// AppThemes.qml
pragma Singleton
import QtQuick
AppThemesPrivate {
}
// AppThemesPrivate.qml
import QtQuick
QtObject {
id: appThemes
readonly property list<string> themes: ["light","dark"]
property string currentName: "light"
readonly property AppStyle current: appThemes[currentName] || light
property AppStyle light: AppStyle {
}
property AppStyle dark: AppStyle {
fontSize: 14
palette: Palette {
alternateBase: "#000"
base: "#000"
button: "#111"
buttonText: "#fff"
dark: "#666"
highlight: "#d73"
highlightedText: "#000"
light: "#000"
mid: "#444"
midlight: "#333"
placeholderText: "#80000000"
shadow: "#888"
text: "#fff"
window: "#222"
windowText: "#fff"
}
}
}
// AppStyle.qml
import QtQuick
import QtQuick.Controls
QtObject {
property int fontSize: 10
property Palette palette: Palette {
alternateBase: "#fff"
base: "#fff"
button: "#eee"
buttonText: "#000"
dark: "#999"
highlight: "#38c"
highlightedText: "#fff"
light: "#fff"
mid: "#bbb"
midlight: "#ccc"
placeholderText: "#80000000"
shadow: "#777"
text: "#000"
window: "#fff"
windowText: "#000"
}
}
// AppButton.qml
import QtQuick
import QtQuick.Controls
Button {
font.pointSize: AppThemes.current.fontSize
}
// AppLabel.qml
import QtQuick
import QtQuick.Controls
Label {
font.pointSize: AppThemes.current.fontSize
}
You can Try it Online!
References: