7

I have Theme1.js which has the property variables related to Theme 1 styling, Similarly like this I have for Theme 2, Theme2.js Now in main.qml, If I click on the MouseArea, The Theme should toggle between Theme1 to Theme2. I found that conditional import Statements doesn't exist in QML. Is there any other way for this.?

Theme1.js

var color="red";
var textString="This is Theme1"

Theme2.js

var color="green";
var textString="This is Theme2"

main.qml

import QtQuick 2.3
import QtQuick.Window 2.2
import "Theme1.js" as Theme //default Theme 

Window {
    visible: true
    color:Theme.color

    MouseArea {
        anchors.fill: parent
        onClicked: {
            //Change Theme 1 to Theme 2. Basically Toggle Theme here

        }
    }

    Text {
        text: Theme.textString
        anchors.centerIn: parent
    }
}
snehitha
  • 91
  • 1
  • 6

1 Answers1

6

First of all, it is not advised to use a js-library to store values, you will bind to later. This is as it is not advised to bind to var-types. You should consider transforming your libraries into QtObject-singletons.

Use libraries only as libraries for functions.

To change the theme, you might have a one singleton Style

pragma Singleton
import QtQuick 2.0

QtObject {
    property Theme current: theme1
    property Theme theme1: Theme1 { }
    property Theme theme2: Theme2 { }
}

with Theme.qml being something like:

import QtQuick 2.0
QtObject {
    property color color0
    property color color1
    property color colorX
}

and then Theme1.qml

import QtQuick 2.0
Theme {
    color0: 'green'
    color1: 'blue'
    colorX: 'red'
}

and Theme2.qml being:

import QtQuick 2.0
Theme {
    color0: 'red'
    color1: 'pruple'
    colorX: 'yellow'
}

Then you bind your properties to color: Style.current.colorX

To change the style, assign another theme to Style.current


EDIT: It might be an optimization, to use intermediate variables to shorten the paths to the value. It adds the convenience of not needing to use Style.current.color0 but to use Style.color0 instead at least.

You might use this instead for your Style.qml

pragma Singleton
import QtQuick 2.0

Theme { // Use Theme instead of QtObject
    property Theme current: theme1
    property Theme theme1: Theme1 { }
    property Theme theme2: Theme2 { }

    // Bind the `Theme`s properties as intermediate variables to the current Theme.
    color0: (current && current.color0 ? current.color0 : 'defaultColor0')
    color1: (current && current.color1 ? current.color1 : 'defaultColor1')
    colorX: (current && current.colorX ? current.colorX : 'defaultColorX')
}
  • 1
    A useful resource for [Singleton based QML Styling](https://stackoverflow.com/questions/15257946/declare-global-property-in-qml-for-other-qml-files). – m7913d Jun 06 '17 at 12:46
  • 1
    Could you explain your point a bit more? ofc. you might inline the `Them1/2`-declarations in `Style` or you might use dynamic instantiation to reduce the memory consumption. But to reduce the amount of implicit classes, I think it is beneficial to have one common class `Theme` from which you inherit the concrete `Theme`s. Further having this common base class makes sure, all your styles have the same properties, you are less prone to spelling mistakes, you enable code completion for QtCreator etc... – derM - not here for BOT dreams Jun 06 '17 at 12:53
  • 1
    The only inconvenience is that your bindings are longer now, i.e. you always have to type `.current.`. – m7913d Jun 06 '17 at 12:59
  • 1
    You are right. I added a suggestion, on how to remove this inconvenience. It might even improve performance [if this counts as intermediate variable](http://doc.qt.io/qt-5/qtquick-performance.html#bindings) . I have no data concerning this. At least it allows us to remove any `null`-checks within the application it self. (current might be not initialized at the startup and errors might be thrown) – derM - not here for BOT dreams Jun 06 '17 at 14:57