QQuickImageProvider and Designer

  • I'm trying to use QtQuick/QML for game UI (with nya engine). I'd like QML to load images and other resources from my game's engine resource system.

    For loading images, I can register a QQuickImageProvider for resource system. This will work in game. However, I suppose it won't work in Designer, since it knows nothing about my custom provider. Is there any way to solve this? I would be glad to do any of below, if possible:

    a) Avoid use of QQuickImageProvider and make it so QMLEngine use my resource system even when image source is specified simply as "textures/some_image.png". If this is possible, then the game will work with packed resources, and Designer will work with unpacked resources with no problems.

    b) Find a way to make Designer aware of my QQuickImageProvider. Is this possible via a plugin for QtCreator, or should I build QtCreator from scratch with my Provider built-in?

  • OK, I think I found a solution. It's not straightforward.

    First, in Qt 4.x things were much simpler, because I could just register QAbstractFileEngine which would redirect ALL file access to my own resource system. Unfortunately, this API is now private and is not recommended for use. It's a VERY bad decision on part of Qt team, as it makes Qt nearly unusable for games without bending over backwards :(

    Now, what can we do? I need to load images and QML files from QMLEngine from my resource system. There is no way to do this universally, so I'll have to use two separate hacks. But it all hinges on QQmlAbstractUrlInterceptor. It's a 3-step plan:

    1. Register my QQmlAbstractUrlInterceptor with the following rules:
    • If Engine is trying to load a QML file, change its URL to "http://my_provider/filename.qml"
    • If Engine is trying to load something else (image), change its URL to "image://my_provider/filename.png"
    1. Register my QQuickImageProvider with id "my_provider", so that when I intercept and change URL in the game, it will be loaded through it.
    2. For QML files, register my own QNetworkAccessManager. Instead of network, it will access my resource system.

    I haven't yet tried this, but it probably should work. That said, I do not like this very much. So many ugly solutions for what should be a simple task!

  • Lifetime Qt Champion


    While not necessarily recommended, you can use Qt's private API with the limitation that it might disappear in a future version so you're basically tied with the Qt version you build your application against.

    As for a solution on how to redirect everything through something else than QAbstractFileEngine, I'd recommend posting that question to the interest mailing list. You'll find there Qt's developers/maintainers. This forum is more user oriented.

Log in to reply