Set application to remember theme: dark vs light - qt

There is this QML setup to remember application theme:
import QtQuick.Controls 2.0 as QQC2
QQC2.ApplicationWindow {
id: standaloneWindow // ID is required to be able to get properties
Material.theme: Material.Dark // Can be either Dark or Light
Component.onCompleted: {
// On launch, read theme from settings file
standaloneWindow.Material.theme = appSettings.materialTheme
}
Component.onDestruction:{
// On close, write theme to settings file
appSettings.materialTheme = standaloneWindow.Material.theme
}
Settings {
id: appSettings
category: "Theme"
property int materialTheme // Store theme as "int" type in settings file
}
}
Problem
At the very first launch (for example when settings file is deleted), the theme cannot be started with Dark. At the very first launch, the app always starts with Light theme, no matter what!
Cause
When there is no settings file, the appSettings.materialTheme becomes 0 which is default for int type. Consequently, 0 is equivalent to Material.Dark enum. That's why application always starts at dark mode when there is no settings file.
Question
How can I make the application start with light mode, even when there is no settings file?
Tried so far
I tried to use alias rather than int, but standaloneWindow doesn't have a property to bind to Material.theme:
Settings {
// ...
property alias materialTheme: standaloneWindow.???
}
Any suggestion?

As commented by #Mitch , problem got resolved by:
Settings {
id: appSettings
category: "Theme"
// Set dark theme to be default for the very first launch (when settings file is NOT available)
property int materialTheme: Material.Dark
}

Related

How to create custom local template object in qml?

In my qml file i have a lot of uniform objects with few differencies (id for example).
I want to use "Don't Repeat Yourself" principle
So i want create custom local template, which i'll can append with unique properties on using.
I know about creating separate .qml file, but this templates are too small for this mechanism (It's seems wired for me to create separate .qml file for red squares with 2px border)
Is there any meachanism for small templates in qml?
Qt 5.15.0 adds support for inline components. Here's the example from the docs:
import QtQuick 2.15
Item {
component LabeledImage: Column {
property alias source: image.source
property alias caption: text.text
Image {
id: image
width: 50
height: 50
}
Text {
id: text
font.bold: true
}
}
Row {
LabeledImage {
id: before
source: "before.png"
caption: "Before"
}
LabeledImage {
id: after
source: "after.png"
caption: "After"
}
}
property LabeledImage selectedImage: before
}

How do I split my QML code into multiple files?

I have just started playing with QML and have a view where I have a bunch of components as follows:
Window {
....
property Component dateTumbler: ControlView {
// Definition follows
}
property Component timeTumbler: ControlView {
// More definition follows
}
// More controls
}
This makes the main QML file very long and cumbersome to edit and maintain. I tried to separate this into different files as follows:
// DateTumblerView.qml
component: DateTumblerView { // Not sure how to inherit here..
// Definition here
}
I'm trying to use it like this:
property component dateTumbler: DateTumblerView {}
However, this never works and the DateTumblerView is never found. I am not sure if I am doing this correctly.
[EDIT]
ControlView is defined as follows:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtMultimedia 5.5
Rectangle {
id: view
property bool darkBackground: false
Text {
id: textSingleton
}
SoundEffect {
id: playCalSound
source: "qrc:/sound/test.wav"
}
}
[END EDIT]
What is the proper way to split QML code into multiple files?
Your DateTumblerView.qml file should look like this:
ControlView {
// More definition follows
}
And you would use it like this:
property Component dateTumbler: DateTumblerView {}
Or:
Component {
id: dateTumbler
DateTumblerView {}
}
Or if you wanted to use it directly:
DateTumblerView {}
It's pretty much the same as when your code was just in one file. Anytime you do <Type> {}, you're inheriting that type and can set or add new properties, functions, and subcomponents. The difference is that it is in a separate file, has a specific name (the name of the file), and you can reuse that code as many times as you want.
For more details, see Defining Custom QML Types for Re-use.

Change icon depending on language in Qt

Is there a standard mechanism for setting language-depending icons in Qt.
If not, would this work and would it be safe:
MyWidget->setIcon(QPixmap(dir.currentPath() + tr("/images/icon_en.png") ));
//icon_en should be translated according to corresponding image names
There is no standard mechanism for setting icon depending on the locale in Qt. Nevertheless, writing your own mechanism is very plain.
IMO, using tr in your code is redundant. This way is much more flexible:
// Get current system locale:
const QString LOCALE = QLocale::system().name(); // For example, result is "en_US"
// Extract language code from the previously obtained locale:
const QString LANG = LOCALE.split('_').at(0); // Result is "en"
// Path to our icons:
const QString PATH = QString(QApplication::applicationDirPath() + "/images");
// Build the path to the icon file:
const QString ICON = QString("%1/icon_%2.png").arg(PATH, LANG);
// Check if the icon for the current locale exists:
if (QFile::exists(ICON)) {
// Set this icon for our window:
setWindowIcon(QPixmap(ICON));
}
else {
// Otherwise fallback to the default icon:
setWindowIcon(QPixmap(PATH + "/icon_default.png"));
}
Generally, the technique you posted is correct. Just few remarks on your code:
Note that QDir::currentPath() does not return the executable directory; it returns the current working directory. Use QApplication::applicationDirPath() instead.
You may also want to use Qt Resource System instead of storing images along with your executable.
You can load an icon from a ressource file.
Then you can specify an alias for specific languages in the ressource file:
<qresource>
<file>cut.jpg</file>
</qresource>
<qresource lang="fr">
<file alias="cur.jpg">cut_fr.jpg</file>
<qresource>
This way when the app is turned to french automatically the alias icon is selected.

Appgyver Supersonic Drawer not showing up

I have tried to show a left drawer in a Steroids Supersonic example application.
I don't have tabs, I use a root view.
I use the following code in the structure.coffee file (this is the only file I changed):
# Read more about app structure at http://docs.appgyver.com
module.exports =
# See styling options for tabs and other native components in app/common/native-styles/ios.css or app/common/native-styles/android.css
rootView:
location: "example#getting-started"
preloads: [
{
id: "learn-more"
location: "example#learn-more"
}
{
id: "using-the-scanner"
location: "example#using-the-scanner"
}
]
drawers:
left:
id: "leftDrawer"
location: "example#drawer"
showOnAppLoad: false
options:
animation: "swingingDoor"
initialView:
id: "initialView"
location: "example#initial-view"
Nothing shows up on the left side. If I change the showOnAppLoad to true, nothing is visible.
What else should I set?
It was a coffeescript error: the creators of the framework were so smart that the compilation depends on indentation. Great thinking...very constructive.
Just in case if anybody visited this page looking for solution:
in structure.coffee file
// the line below should be intended so it become part of array above it
drawers:
left:
id: "leftDrawer"
location: "home#drawer"
...etc

Dot symbol in "type" field of property definition operator

I am using Qt 5.2 and QtQuick 2.2.
In my project I have several modules that are placed in separated directories. My problem is that I can't use dot-separator in typename while defining properties.
For example:
MyRect.qml
import QtQuick 2.2
Rectangle {
id: root
property color rectColor: "white"
color: root.rectColor
}
MyRectInRect.qml
import QtQuick 2.2
import "./" as MyModule
Rectangle {
id: root
property MyModule.MyRect innerRect: MyModule.MyRect { }
// ^ error: Unexpected token `.'; Unexpected token `identifier'
}
I have searched for something that could explain this behavior in the manual, but looks like there is nothing about it there. I guess that dot symbol is not allowed to be used in "type" field of property definition. But is there any way to explicitly define, what component from which module should be used as a type? Cause there may be need of declaring properties with same typenames, but from different modules.
This is a known issue: QTBUG-10822

Resources