Qt 5 Styling: dynamically load qml files

2019-04-12 01:52发布

I am currently trying to extend our application with different style. For each style I have a separate qml file with e.g. color definitions. StyleA.qml:

import QtQuick 2.0
QtObject {
    property color textColorStandard: 'black'
    ...
}

In my main.qml I would like to load the right qml file, based on a software property:

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

    Loader {
        id: myDynamicStyle
        source:  Property.UseThemeA? "StyleA.qml" : "StyleB.qml"
    }
    ...
    Item {
            id: BackGround
            color: myDynamicStyle.textColorStandard
    }
}

unfortunately this approach does not work. Is there any other/better way to accomplish styling?

thanks, michael

标签: c++ qt qml styling
2条回答
甜甜的少女心
2楼-- · 2019-04-12 02:15

Using things loaded in Loader is badly typed, I would rather :

First, create a common ancestor Component for all my styles, e.g :

// AbstractStyle.qml
import QtQuick 2.0;
QtObject {
    property color textColorStandard;
}

Next, derivate it to create custom styles, e.g :

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

// StyleB.qml
import QtQuick 2.0;
AbstractStyle {
    textColorStandard: "green";
}

Then use a strongly typed property in my object that must use a style, e.g:

// 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;
    }
}

That way, there are multiple advantages :

  1. your code doesn't use Strings to identify components, so errors are easier to find and to avoid ;
  2. you can't affect an item that doesn't inherit your style base class, so you won't encounter "undefined property" errors and won't need ducktyping to figure out which information you have in your style object ;
  3. you don't have Loader so you won't have to suffer the nasty "context isolation" between inside and outside the Loader ;
  4. all components will be preloaded at runtime, gaining speed at instanciation, and allowing you to see from the start if there are syntax errors in the Styles, instead of seeing it only when changing current style ;
  5. last but not least, property auto-completion will work in QtCreator as the actual type will be known by the IDE !
查看更多
ゆ 、 Hurt°
3楼-- · 2019-04-12 02:23

Did you try using this instead? The loaded object is store into the item property of the loader and no in the loader directly.

Item {
    id: BackGround
    color: myDynamicStyle.item.textColorStandard
}
查看更多
登录 后发表回答