javascript - Cambia dinámicamente el tema QML en tiempo de ejecución
qt resources (1)
Pude hacerlo funcionar, gracias a otros hilos.
Primero, crea tus temas como este usuario, que hereda de AbstractStyle
, lo que permite mucha más flexibilidad.
https://stackoverflow.com/a/25866188/2425044
Nuestra property
se definirá entonces por el valor devuelto por una función 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;
}
Supongamos que desea cambiar el tema cuando el usuario hace clic en un 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")
}
}
Recuerde, redTheme.qml y blueTheme.qml están contenidos en archivos qrc
que a su vez se compilan en archivos rcc
.
Aquí está la definición de changeTheme(const QString&, const QString&)
, que changeTheme(const QString&, const QString&)
el registro del tema anterior y registra el nuevo:
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;
}
Otros hilos que me han ayudado:
https://wiki.qt.io/Qml_Styling
http://www.slideshare.net/BurkhardStubert/practical-qml-key-navigation (comienza en la diapositiva 34)
De hecho, estoy usando la solución proporcionada aquí: https://stackoverflow.com/a/25864815/2425044
Me gustaría deshacerme de la import "MyTheme.js" as Theme;
declaración para cargar dinámicamente un tema específico en tiempo de ejecución (generalmente elegido por el usuario).
Lo que estoy haciendo actualmente es cargar cada uno de mis archivos Themes.js
en un archivo qrc
:
-
redTheme.qrc
contieneTheme.js
-
blueTheme.qrc
contieneTheme.js
Estos archivos qrc
se compilan en recursos binarios externos ( rcc
) y se cargan desde el directorio binario, usando
registerResource(const QString &rccFileName, const QString &mapRoot = QString())
Hasta ahora, todo funciona. El único problema es que estoy atascado con una declaración de import
en mis archivos QML
:
import "qrc:/redTheme/Theme.js" as Theme
Por lo tanto, a pesar de registrar blueTheme.rcc
como un recurso, nunca será utilizado.