Qt 5 Styling: dynamically load qml files

余生颓废 提交于 2019-11-29 22:56:36

问题


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


回答1:


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 !



回答2:


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
}


来源:https://stackoverflow.com/questions/23518071/qt-5-styling-dynamically-load-qml-files

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!