在运行时动态更改 QML 主题 [英] Dynamically change QML theme at runtime
问题描述
我实际上正在使用此处提供的解决方案:https://stackoverflow.com/a/25864815/2425044
I'm actually using the solution provided here: https://stackoverflow.com/a/25864815/2425044
我想去掉 import "MyTheme.js" as Theme;
语句,以便在运行时动态加载特定主题(通常由用户选择).
I'd like to get rid of the import "MyTheme.js" as Theme;
statement in order to dynamically load a specific theme at runtime (usually chosen by the user).
我目前正在做的是将我的每个 Themes.js
文件加载到一个 qrc
文件中:
What I'm currently doing is loading each of my Themes.js
files in a qrc
file:
redTheme.qrc
包含Theme.js
blueTheme.qrc
包含Theme.js
redTheme.qrc
containsTheme.js
blueTheme.qrc
containsTheme.js
这些qrc
文件被编译成外部二进制资源(rcc
)并从二进制目录加载,使用
These qrc
files are compiled into external binary resources (rcc
) and loaded from the binary directory, using
registerResource(const QString &rccFileName, const QString &mapRoot = QString())
到目前为止,一切正常.唯一的问题是我在我的 QML
文件中遇到了 import
语句:
So far, everything works. The only problem is that I'm stuck with an import
statement in my QML
files:
import "qrc:/redTheme/Theme.js" as Theme
因此,尽管将blueTheme.rcc
注册为资源,但它永远不会被使用.
Thus, despite registeringblueTheme.rcc
as a resource, it will never be used.
推荐答案
多亏了其他线程,我才能让它工作.
I was able to make it work, thanks to other threads.
首先,像这个用户一样创建你的主题,它继承自 AbstractStyle
,提供更大的灵活性.
First off, create your themes like this user does, which inherit from AbstractStyle
, allowing much more flexibility.
https://stackoverflow.com/a/25866188/2425044
我们的 property
将由 JS
函数返回的值定义:
Our property
will then be defined by the value returned by a JS
function:
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
时更改主题:
Let's say you want to change theme when the user clicks on a 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
文件.
Remember, redTheme.qml and blueTheme.qml are contained in qrc
files which are themselves compiled into rcc
files.
这是changeTheme(const QString&, const QString&)
的定义,它注销旧主题并注册新主题:
Here's the definition of changeTheme(const QString&, const QString&)
, which unregisters the old theme and registers the new one:
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;
}
其他对我有帮助的主题:
Other threads that have helped me:
https://wiki.qt.io/Qml_Styling
http://www.slideshare.net/BurkhardStubert/practical-qml-key-navigation(从幻灯片 34 开始)
http://www.slideshare.net/BurkhardStubert/practical-qml-key-navigation (begins at slide 34)
这篇关于在运行时动态更改 QML 主题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!