使用 C++ 更改 QML 单例的 属性

Change property of the QML singleton with C++

我正在实施一个简化的 Ubuntu 类似触摸的调色板(不是每个元素的调色板)。

有一个GlobalPaletteSetting单例:

pragma Singleton

import QtQuick 2.5

QtObject {
    property Palette current: NonePalette {}
}

和一些调色板 类,例如 NonePaletteDark

Palette {
    normal: PaletteValues {
        background: "white"
        backgroundText: "black"
        base: "white"
        baseText: "black"
        foreground: "white"
        foregroundText: "black"
        overlay: "white"
        overlayText: "black"
        field: "white"
        fieldText: "black"
        selection: "pink"
    }
}

因此,可以在 QML 中更改全局调色板:

import "Customization/Palettes/Dark"

//...

DarkPalette {
    id: dark
}

Component.onCompleted: {
    GlobalPaletteSetting.current = dark
}

我想通过设置环境变量来设置全局调色板。就像 QtQuick 样式一样有效。

因此,需要从 C++ 访问 GlobalPaletteSetting。还有一种使用调色板加载 QML 文件并设置 GlobalPaletteSetting.current 的方法。

怎么做?

这是我想出的代码:

QQmlComponent component(engine());
const char *source =
        "import QtQuick 2.0\n"
        "import Components 1.0\n"
        "QtObject {\n"
        "    property var style: CustomStyle\n"
        "    function setColor(c) { CustomStyle.headerColor = c; }\n"
        "}";
component.setData(source, QUrl());
QObject *item = component.create();
QObject *style = qvariant_cast<QObject*>(item->property("style"));
style->setProperty("headerColor", QColor(255, 0, 0));

这里,CustomStyle是我的样式定义,单例。您可以在 https://goo.gl/ItJGIf

找到完整示例

使用 objectName 的建议对我不起作用 - 无论我将它放在单例组件的顶层还是子项中,findChild returns 0 . 它也不适用于常规组件的顶层,仅适用于其子组件。你可以在 https://goo.gl/Iqj9Ap

找到我的尝试

关于你的第二个问题,关于在运行时加载你的样式定义,你可以调整上面的代码-使用setDataloadUrl加载组件定义,使用create创建实例,然后设置实例。事实上,您可以 engine()->rootContext()->setContextProperty("style", ...) 以便 QML 中的所有内容都可以访问 'style' 变量,这可能比使用单例更容易。