Force Loader reload



  • I have a Quick Controls 2 app and I need to expose the QQmlEngine inside it.

    Maybe something like this:

    MyEngine {
    id: myEngine
    }

    and then I can call myEngine.clear()

    The clear() function is in a C++ class called MyEngine, like this

    void MyEngine::clear()
    {
    myCurrentQmlEngine->clearComponentCache();
    }

    However, I can't find out how to make myCurrentQmlEngine reference the current QML Engine (QQmlEngine). I imagine that needs to happen in MyEngine's constructor.

    Anyone know how to do this?

    (Or does anyone know a better way of forcing a Loader to reload without pulling from the qml engine's cache?)



  • @JeTSpice You don't need an instantiable type nor do you need to instantiate a type in QML. Use setContextProperty with a QObject based object which has a slot or a Q_INVOKABLE method which calls clearComponentCache(). You can even subclass QQmlApplicationEngine, create an object out of it in C++ and set itself as its own context property and use it to load and run QML. Then use it as a global object in QML.

    class MyEngine : public QQmlApplicationEngine
    {
        Q_OBJECT
    public:
        Q_INVOKABLE void clear() { clearComponentCache(); }
    ...
    
    //main.cpp
        MyEngine engine;
        engine.rootContext()->setContextProperty("myEngine", &engine);
        engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    
    // qml javascript
    myEngine.clear()
    


  • Thank you for your help.
    I'm getting a compile error:

    invalid use of incomplete type 'class QQmlContext'

    at this line:

    engine.rootContext()->setContextProperty("myEngine", &engine);

    It looks like that means rootContext does not yet exist at that moment?

    Here is my main.cpp file:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    class MyEngine : public QQmlApplicationEngine
    {
        Q_OBJECT
    public:
        Q_INVOKABLE void clear() { clearComponentCache(); }
    };
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
    
        MyEngine engine;
        engine.rootContext()->setContextProperty("myEngine", &engine);
        engine.load(QUrl(QLatin1String("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        return app.exec();
    }
    


  • @JeTSpice That's a normal situation in C++ - you just have to add a header:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext> //this!
    
    class MyEngine : public QQmlApplicationEngine
    {
    

    It's also possible that you have to move MyEngine in its own file or add some macro directive (I don't remember which one) in main.cpp. Otherwise Qt's moc preprocessor can't create the needed metaclass.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.