How to locally disable qrc in QML

From Qt Wiki
Jump to navigation Jump to search
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

By default, when you load any file in QML using QRC (Qt Resource System), all files down the hierarchy tree are loaded using resource system, too. This is nice and handy for most use cases, because it allows you to switch to QRC without big changes to the source code.

But what if you are using resources, and suddenly need to load a non-qrc file? For example, in an app you are developing, a certain module, or game's save file, can be provided by user at runtime, using relative path. Currently, QML will not allow that - once you've started using resources, the declarative engine loads all files using QRC scheme.

I faced the same problem and found a pretty nice and easy solution: QRC can be locally disabled. It will not break anything - in fact, after turning the QRC scheme off, you can still load a file from resource system, and the QML engine will automatically reapply the scheme.

Here's what needs to be done (to make the example simple, I assume we need to disable QRC in a Loader element):

  1. In C++, define a signal to be emitted before the new file is to be loaded, and a slot to receive the signal. Connect them together, and add as context properties to your QML. In this case, I'll use "void disableQrcSignal(QObject *object);" as signal, and "void disableQrcSlot(QObject *object);" as slot
  2. Before you change "source" property of your Loader, send "disableQrcSignal(loaderId)" signal.

Here's a snippet (I'm using a global property, fileToLoad, to store the path):

Loader {
 id: loader
 source: {
 disableQrcUse(loader);
 return fileToLoad; // A relative path or QRC path!
 }
}

This ensures that QRC is disabled before you start loading the file. Of course, it can also be made in other ways.

In your disableQrcSlot() body, use this code:

void MyClass::disableQrcSlot(QObject *object)
{
 // This assumes that QDeclarativeEngine is available
 QDeclarativeContext *context = engine()->contextForObject(object);
 // This line clears QRC scheme from object's context
 context->setBaseUrl(QUrl::fromLocalFile(""));
}