Qt 5 样式:动态加载 qml 文件

use*_*207 4 c++ qt styling qml

我目前正在尝试以不同的风格扩展我们的应用程序。对于每种样式,我都有一个单独的 qml 文件,其中包含颜色定义等。样式A.qml:

import QtQuick 2.0
QtObject {
    property color textColorStandard: 'black'
    ...
}
Run Code Online (Sandbox Code Playgroud)

在我的 main.qml 中,我想根据软件属性加载正确的 qml 文件:

import QtQuick 2.0
Item {
    id: mainPanel
    ....

    Loader {
        id: myDynamicStyle
        source:  Property.UseThemeA? "StyleA.qml" : "StyleB.qml"
    }
    ...
    Item {
            id: BackGround
            color: myDynamicStyle.textColorStandard
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是这种方法不起作用。还有其他/更好的方法来完成造型吗?

谢谢,迈克尔

The*_*roo 5

使用 Loader 中加载的内容是错误的类型,我宁愿:

首先,为我的所有样式创建一个共同的祖先组件,例如:

// AbstractStyle.qml
import QtQuick 2.0;
QtObject {
    property color textColorStandard;
}
Run Code Online (Sandbox Code Playgroud)

接下来,派生它以创建自定义样式,例如:

// StyleA.qml
import QtQuick 2.0;
AbstractStyle {
    textColorStandard: "blue";
}

// StyleB.qml
import QtQuick 2.0;
AbstractStyle {
    textColorStandard: "green";
}
Run Code Online (Sandbox Code Playgroud)

然后在我的对象中使用必须使用样式的强类型属性,例如:

// main.qml
import QtQuick 2.0
Item {
    id: base;

    Component { id: compoStyleA; StyleA { } }
    Component { id: compoStyleB; StyleB { } }

    property AbstractStyle currentStyle : {
        var tmp = (Property.UseThemeA ? compoStyleA : compoStyleB); // choose component
        return tmp.createObject (base); // instanciate it and return it
    }

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

这样,有多个优点:

  1. 您的代码不使用字符串来标识组件,因此更容易发现和避免错误;
  2. 您不能影响不继承样式基类的项目,因此您不会遇到“未定义的属性”错误,并且不需要鸭子类型来确定样式对象中包含哪些信息;
  3. 你没有 Loader,所以你不必遭受 Loader 内部和外部之间令人讨厌的“上下文隔离”;
  4. 所有组件都将在运行时预加载,在实例化时提高速度,并允许您从一开始就看到样式中是否存在语法错误,而不是仅在更改当前样式时才看到;
  5. 最后但并非最不重要的一点是,属性自动完成功能将在 QtCreator 中起作用,因为 IDE 会知道实际类型!