Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Force Loader reload
Forum Updated to NodeBB v4.3 + New Features

Force Loader reload

Scheduled Pinned Locked Moved Solved QML and Qt Quick
5 Posts 2 Posters 3.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    JeTSpice
    wrote on last edited by
    #1

    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?)

    E 1 Reply Last reply
    0
    • J JeTSpice

      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?)

      E Offline
      E Offline
      Eeli K
      wrote on last edited by
      #2

      @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()
      
      1 Reply Last reply
      0
      • J Offline
        J Offline
        JeTSpice
        wrote on last edited by
        #3

        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();
        }
        
        E 1 Reply Last reply
        0
        • J JeTSpice

          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();
          }
          
          E Offline
          E Offline
          Eeli K
          wrote on last edited by
          #4

          @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.

          1 Reply Last reply
          1
          • J Offline
            J Offline
            JeTSpice
            wrote on last edited by
            #5

            It works now.
            I had to recreate MyEngine as an external file (.h file and .cpp file)

            A co-worker found out that MyEngine needs to delay clearing the cache or it will conflict with rendering (painting, i think its called in qml). A delay interval of 0 (zero) works.

            As far as forcing the Loader to reload, we found that the source url needs to be absolute, for instance:

            "File:///Users/JohnDoe/Documents/RedRectangle.qml"
            

            The source url can point to a file in a qml project.
            In our case, we don't set the Loader.source to an empty string and then re-set it back. Simply calling myengine.clear() works.

            Solved. Thanks for your help.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved