在运行时动态更改 QML 主题

Gré*_*rel 6 javascript resources qt qml

我实际上正在使用此处提供的解决方案:https ://stackoverflow.com/a/25864815/2425044

我想删除该import "MyTheme.js" as Theme;语句,以便在运行时动态加载特定主题(通常由用户选择)。

我目前正在做的是将每个Themes.js文件加载到一个qrc文件中:

  • redTheme.qrc包含Theme.js
  • blueTheme.qrc包含Theme.js

这些qrc文件被编译成外部二进制资源 ( rcc) 并从二进制目录加载,使用

registerResource(const QString &rccFileName, const QString &mapRoot = QString())
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切正常。唯一的问题是我被文件import中的一条语句所困扰QML

import "qrc:/redTheme/Theme.js" as Theme
Run Code Online (Sandbox Code Playgroud)

因此,尽管注册blueTheme.rcc为资源,但它永远不会被使用。

Gré*_*rel 6

感谢其他线程,我能够使其工作。

首先,像该用户一样创建您的主题,它继承自AbstractStyle,从而提供更大的灵活性。

/sf/answers/1810633191/

然后我们的property意志由函数返回的值定义JS

import "qrc:/graphics/componentCreation.js" as Theme

Item
{
    id: homeViewItem
    anchors.centerIn: parent

    // Load default theme at startup
    property AbstractTheme currentTheme: Theme.createThemeObject(homeViewItem, "qrc:/redTheme/redTheme.qml");

    Rectangle 
    {
        color: currentTheme.textColorStandard;
    }
}
Run Code Online (Sandbox Code Playgroud)

组件创建.js

// Create themes components and load them in the apps' QML files

var component;
var sprite;

function createThemeObject(item, themePath)
{
    component = Qt.createComponent(themePath);
    sprite = component.createObject(item);

    if (sprite === null)
        console.log("componentCreation.js: error creating " + themePath + " object");
    else
        return sprite;
}
Run Code Online (Sandbox Code Playgroud)

假设您想在用户单击时更改主题Button

Button
{
    id: themeButton
    text: "Change to blue theme"
    onClicked:
    {
        // Remove content of redTheme.rcc, register blueTheme.rcc
        cpp_class.changeTheme("redTheme", "blueTheme")
        // blueTheme's content is now available, let's fill its content into a QML object
        currentTheme = Theme.createThemeObject(homeViewItem, "qrc:/blueTheme/blueTheme.qml")
    }
}
Run Code Online (Sandbox Code Playgroud)

请记住,redTheme.qmlblueTheme.qml包含在qrc本身编译成rcc文件的文件中。

这是 的定义changeTheme(const QString&, const QString&),它取消注册旧主题并注册新主题:

void cpp_class::changeTheme(const QString &oldTheme, const QString &newTheme)
{
    bool un = QResource::unregisterResource(QCoreApplication::applicationDirPath() + "/data/themes/" + app + "/" + oldTheme + ".rcc");
    if (!un)
        std::cerr << oldTheme.toStdString() << "could not be unregistered" << std::endl;
    bool in = QResource::registerResource(QCoreApplication::applicationDirPath() + "/data/themes/" + app + "/" + newTheme + ".rcc");
    if (!in)
        std::cerr << newTheme.toStdString() << "could not be registered as an external binary resource" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

其他对我有帮助的主题:

https://wiki.qt.io/Qml_Styling

http://www.slideshare.net/BurkhardStubert/practical-qml-key-navigation(从幻灯片 34 开始)