0

As part of a Qt Designer hacking, I'm interested in removing a resource in runtime (specifically :/trolltech/widgetbox/widgetbox.xml). Refer to the end of the post for more detail about the context.

My obvious (and failed) attempt was:

QFile(":/trolltech/widgetbox/widgetbox.xml").remove();

but it returned an error.

My next attempt was to use Q_CLEANUP_RESOURCE(widgetbox), but the functions it expands to are only available within a private component of Qt Designer (QDesignerComponents).

Another attempt was to clear the content of the file, but it is read-only:

QFile f(":/trolltech/widgetbox/widgetbox.xml");
if (f.open(QFile::WriteOnly)) { ... } // returns false

I've also tried to overwrite it in the Qt resource's filesystem by defining my own :/trolltech/widgetbox/widgetbox.xml. I'm able to open the file but it fails to retrieve data, I guess because it is a duplicate resource (aliasing the resource to an unused name makes the application to print out the content correctly). On the other hand, the list of widgets is presented correctly.

QFile f(":/trolltech/widgetbox/widgetbox.xml");
if (f.open(QFile::ReadOnly)) {
    qDebug() << "{";
    qDebug() << f.readAll(); // shows nothing
    qDebug() << "}";
}

Is there any way to modify/remove/replace a resource file in runtime?


In the case you consider this an XY problem I'll explain the whole context: I'm integrating Qt Designer into my own IDE by making small tweaks to the standalone one. Basically, I've added a compilation flag to generate a dynamic library instead of an executable, and added some options to expose the main window.

In this IDE I want to add an option to avoid the user to use the default widgets and restrict the list to a set of custom ones. The resource I mention is the file containing the list of widgets available in Qt Designer by default. Additional widgets can be easily included via plugins, but I haven't found a way to remove default ones.

One option I have is to make that load optional, but it will produce a cascade of changes through many projects. I'd like to avoid modifying Qt Designer so much.

cbuchart
  • 10,847
  • 9
  • 53
  • 93

1 Answers1

3

You are using Qt Designer already, so first of all you should include it in your build, and secondly you will have access to all of its classes - no such thing as a "private" component anymore, it's your code now. Make it work for you!

Qt resources can be compiled-in or generated in a separate binary. You could put this resource into a separate binary and then easily load and unload it via registerResource/unregisterResource.

QFile uses a virtual file system based on QAbstractFileEngine. The implementation of QAbstractFileEngineHandler::create acts as a filter and can catch the request and let your file engine handle it if desired. E.g. your file engine could simply fail on open - this is equivalent to deleting the resource.

Note that since Qt 5 the QAbstractFileEngine is not public anymore and presumably Qt folks are looking at replacing it with something else. To use these APIs, you need to add qt += core-private to your project's qmake file.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • Thanks @kuba-ober! I'll take a look at the file engine and the `registerResource`, it will take me a time to test, but I'll let you know! – cbuchart Sep 26 '17 at 14:10
  • BTW, regarding the modifications the thing is that the client wants to _be able to migrate to future versions of Qt_, so I'd like to reduce the amount of work done in order to catch up with newer versions of Qt as fast as possible. – cbuchart Sep 26 '17 at 14:11
  • 2
    You could set up a private git source repository that tracks the qt base repository's designer folder. Use a [sparse checkout](https://stackoverflow.com/questions/4114887/is-it-possible-to-do-a-sparse-checkout-without-checking-out-the-whole-repository) and a shallow pull to pull only the required code. Then add your changes to the repository. When it's time to upgrade to a newer Qt version, rebase your branch. You might get a few conflicts, but those will be only where Qt code and your code changes overlap. You can add that project as a submodule to your project's git repo. No git = SOL. – Kuba hasn't forgotten Monica Sep 26 '17 at 14:21
  • The `registerResource` suggestion was very helpful, thanks! – cbuchart Sep 26 '17 at 15:00