Switch up the QML theme in real-time

I am currently implementing a solution found here:

My goal is to remove the import "MyTheme.js" as Theme; statement so that I can dynamically load a specific theme at runtime, usually selected by the user.

The approach I am taking involves loading each of my Themes.js files in separate qrc files:

  • redTheme.qrc includes Theme.js
  • blueTheme.qrc includes Theme.js

These qrc files are compiled into external binary resources (rcc) and then loaded from the binary directory using:

registerResource(const QString &rccFileName, const QString &mapRoot = QString())

Everything is functioning correctly so far. However, the issue I am facing is being locked into an import statement within my QML files:

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

As a result, even if I register blueTheme.rcc as a resource, it will not be utilized.

Answer №1

I found a solution by consulting various forum threads.

Start by developing your themes similar to the approach of this user, inheriting from AbstractStyle for increased flexibility.

The property will be determined by the output of a JS function:

import "qrc:/graphics/componentCreation.js" as Theme

Item
{
    id: homeViewItem
    anchors.centerIn: parent

    // Load default theme during launch
    property AbstractTheme currentTheme: Theme.createThemeObject(homeViewItem, "qrc:/redTheme/redTheme.qml");

    Rectangle 
    {
        color: currentTheme.textColorStandard;
    }
}

componentCreation.js

// Generate theme components and integrate them into the QML files of the apps

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

To switch themes when a user clicks a Button:

Button
{
    id: themeButton
    text: "Change to blue theme"
    onClicked:
    {
        // Clear redTheme.rcc content, add blueTheme.rcc content
        cpp_class.changeTheme("redTheme", "blueTheme")
        // Blue theme's content is now accessible, insert it into a QML object
        currentTheme = Theme.createThemeObject(homeViewItem, "qrc:/blueTheme/blueTheme.qml")
    }
}

Keep in mind that redTheme.qml and blueTheme.qml are stored in qrc files compiled into rcc files.

This is the implementation of

changeTheme(const QString&, const QString&)
, which deactivates the old theme and enables 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;
}

Additional helpful resources include:

(starting at slide 34)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to access props from a different file in a React application?

I am facing a challenge with my two files: EnhancedTableHead and OrderDialog. I need to access the props data from EnhancedTabledHead in my OrderDialog file. Is there a way to achieve this? Here is how my files are structured: //OrderDialog.jsx import ...

What could be causing the progress bar to malfunction?

I have encountered an issue with my basic progress bar. It seems to work fine when I include only one progress element in my HTML page. However, if I add another one, the first one works as expected while the second one does not. You can view my code on C ...

Summing values in es6 (TypeScript) without explicitly knowing their corresponding keys

I am facing a challenge with an object that has changeable keys, which I do not want to rely on. The keys in this object are not fixed. Here is an example: interface Inf { [key: string]: number } const obj: Inf = { '2020-01-01': 4, '2 ...

What is the best way to send a selected value to a different function in order to retrieve data from a JSON file based on that

I have been working on writing HTML and JavaScript code to extract data from a JSON file. Here is a snippet of my HTML code: <div class="section"> <div class="sectionTitle"> <h3>Configuration</h3> </div> &l ...

There was an error in the code: Unexpected token M

Is there a solution for this error that anyone can share? The Google Developer Tools are not able to identify the exact location of the problematic code, making troubleshooting difficult. I am using Meteor and MongoDB. I have looked into Unexpected toke ...

Analyzing Data for Distributed / External Pages

Our team is currently exploring options for tracking metrics on content we produce for external pages. We are considering various approaches such as creating our own JavaScript, using a tracking pixel, or adapting Google Analytics to fit our needs. We wou ...

The ng-change directive is used on a dropdown to modify the styling of another HTML element

I need the icon to the left of the input in my HTML form to change based on whether the user selects male or female. However, I am facing an issue where when switching from nothing to female, the icon does not update immediately (even though the ng-change ...

Pictures acting erratic following the implementation of two setTimeout functions

I encountered an issue while developing a pong game using html/css/javascript. Everything was going smoothly until I introduced a second setTimeout() function. Here is the snippet of my html code: <!DOCTYPE html> <html> <head> <scrip ...

Ways to ensure a for loop waits until an Async call is successful before proceeding

Hey there! Currently, I am working on creating a batch update for my local store using a for loop and asynchronous Ajax calls. However, I'm facing an issue where the loop continues running even before the Ajax call has successfully completed. Is ther ...

Encountering a GET-error while trying to nest jQuery/json calls: Resolution Update

My goal is to utilize services for ip-lookup and geo-lookup to pinpoint a visitor's location on a map. This information will be stored in a database and used to display live user locations on a dashboard. Currently, I am working on a script that, whe ...

There is an issue with the JSON format being received by fetch in JS when using json_encode in php

Recently, I encountered an issue with my JavaScript function that retrieves data from a PHP page. In the JS code block: fetch("print.php) .then(function (r) { return r.json() }) .then(function (values) { ...... ...... ...

What is the best method for customizing the color of angularjs spinners?

As I delve into developing an AngularJS application, my focus has been on seamlessly integrating an AngularJS spinner. Taking it a step further, I managed to tailor some of the spin-kit CSS properties to customize the appearance and behavior of the spinn ...

Removing Items from Orders

Stored in my MongoDB is the following JSON data: [ { "orderItems": [ "606808d2d7351b0c52d38634", "606808d2d7351b0c52d38635" ], "status": "Pending", ...

Verifying that the code runs only once the changes to a monitored property have been successfully implemented in the user interface

When working with AngularJS, how can one ensure that code is executed only after a change to a watched property has fully taken effect in the UI? For instance, imagine that the visibility of a loading indicator is tied to the value of an isLoading propert ...

Ways to calculate the memory utilization of a JavaScript object

Suppose I want to compare the efficiency of storing bits of a static canvas/image with Alpha more or less than 0.5 using an "array of array of number" versus an "array of string," which would be better in terms of memory usage and speed? var c = $('m ...

Using the ternary operator to insert elements from one JavaScript array into another array

In my React form, I am dealing with an array of objects that represent different fields. Depending on a boolean state, I need to dynamically change the sequence of fields displayed. While I have no trouble inserting a single object into the array, I am s ...

Helping React and MUI components become mobile responsive - Seeking guidance to make it happen

My React component uses Material-UI (MUI) and I'm working on making it mobile responsive. Here's how it looks currently: https://i.sstatic.net/kxsSD.png But this is the look I want to achieve: https://i.sstatic.net/kJC2m.png Below is the code ...

A guide to transferring modules between component files in JavaScript

My query pertains to the handling of imports in web pages. When a file is imported into another, do the declarations and imports from the imported file become available in the file where it is being imported? A suggestion was made for me to import a compo ...

Verification response parameter not received from Google Authentication Express

I've been working on implementing a "sign in with Google" feature for my localhost website. Despite receiving the POST request, I noticed that it lacks the credential parameter. I'm unsure if this issue lies within the code or the API configurati ...

Changing name based on variable value in Angular

I am facing a challenge in my Typescript code where I have two global variables: private myVar1 = 10; private myVar2 = 150; In the HTML, there is a custom element that can accept a [name] attribute. For example, this is how the conditional name on my ele ...