运行时通过鼠标点击动态更改QML主题

7
我有一个名为Theme1.js的文件,其中包含与主题1样式相关的属性变量。类似地,我也有Theme2.js文件。 现在,在main.qml中,如果我点击MouseArea,则主题应在主题1和主题2之间切换。我发现QML中不存在条件导入语句。还有其他方法吗?
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
    }
}
1个回答

6
首先,不建议使用js库来存储稍后绑定的值,这样做可能会导致问题。这是因为不建议绑定var类型。您应该考虑将您的库转换为QtObject单例。
仅将库用作函数库。
要更改主题,您可以有一个单例Style
pragma Singleton
import QtQuick 2.0

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

Theme.qml,类似于:

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

然后Theme1.qml

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

Theme2.qml是:

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

然后将您的属性绑定到 color: Style.current.colorX

要更改样式,请将另一个主题分配给 Style.current


编辑:使用中间变量来缩短到值的路径可能是一种优化方法。这样做可以方便地不需要使用Style.current.color0,而是至少使用Style.color0

您可以将此代码用于您的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
一个有用的资源,关于基于Singleton的QML样式 - m7913d
1
你能再详细解释一下你的观点吗?当然,你可以在Style中内联Them1/2声明,或者使用动态实例化来减少内存消耗。但是为了减少隐式类的数量,我认为拥有一个共同的Theme基类并从中继承具体的Theme是有益的。进一步地,拥有这个共同的基类可以确保所有的样式都有相同的属性,你不容易出现拼写错误,可以启用QtCreator的代码完成等等... - derM
1
唯一的不便之处是你的绑定现在更长了,即你总是需要输入 .current. - m7913d
1
你是对的。我提出了一些建议,可以消除这种不便。如果这被视为中间变量,则可能会提高性能(http://doc.qt.io/qt-5/qtquick-performance.html#bindings)。我没有任何相关数据。至少它允许我们在应用程序内部删除所有“null”检查(当前在启动时可能未初始化,可能会引发错误)。 - derM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接