Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically change QML Theme at runtime on MouseClick

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
    }
}
like image 217
snehitha Avatar asked Jun 06 '17 12:06

snehitha


1 Answers

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')
}
like image 169
derM Avatar answered Nov 24 '22 00:11

derM