2016-03-31 2 views
3

Я на самом деле, используя решение, предложенное здесь: https://stackoverflow.com/a/25864815/2425044Динамически изменить QML тему во время выполнения

Я хотел бы избавиться от 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()) 

До сих пор все работает. Единственная проблема заключается в том, что я застрял с import заявления в моих QML файлах:

import "qrc:/redTheme/Theme.js" as Theme 

Таким образом, несмотря на регистрацию blueTheme.rcc в качестве ресурса, он никогда не будет использоваться.

ответ

1

Я смог заставить его работать, благодаря другим темам.

Прежде всего, создайте свои темы, как этот пользователь, которые наследуют от AbstractStyle, что обеспечивает гораздо большую гибкость.

https://stackoverflow.com/a/25866188/2425044

Наши 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; 
    } 
} 

componentCreation.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; 
} 

Допустим, вы хотите изменить тему когда пользователь нажимает на 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") 
    } 
} 

Помните, что redTheme.qml и blueTheme.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; 
} 

Другие темы, которые помогли мне:

https://wiki.qt.io/Qml_Styling

http://www.slideshare.net/BurkhardStubert/practical-qml-key-navigation (начинается на слайде 34)

Смежные вопросы