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. Hot reloading QML with QRC file.
Qt 6.11 is out! See what's new in the release blog

Hot reloading QML with QRC file.

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
6 Posts 4 Posters 3.3k Views 2 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.
  • EmilieGE Offline
    EmilieGE Offline
    EmilieG
    wrote on last edited by
    #1

    Hi all,

    I've spend 2hours trying to reload my QML within my running application.. with no luck.!
    I just want to have a hot key so that I can decide when developing when to reload everything.
    I found a few ways of doing it (here and here ) but nothing worked properly, I manage to get some components being reloaded on the fly properly but not everything...

    I nailed it down to a small failure case.
    I'm using a qrc file to manage all my qml. and ressource in my qml.qrc are handled as follow:

    <RCC>
        <qresource prefix="/">
            <file alias="main.qml">./main.qml</file>
        </qresource>
        <qresource prefix="/Bar">
            <file alias="Foo.qml">./Foo.qml</file>
        </qresource>
    </RCC>
    
    

    My main.qml looks like this

    import "qrc:/Bar"
    ApplicationWindow {
        id: root
        visible: true
        width: 1920
        height: 1080
        Foo {
          anchors.fill: parent
        }
    }
    

    My main.cpp

    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        QQmlApplicationEngine engine;
        App _app;
        engine.rootContext()->setContextProperty(QStringLiteral("app"), &_app);
        _app.set_engine(&engine);
        QUrl source (QStringLiteral("qrc:/main.qml"));
        engine.load(source);
        if (engine.rootObjects().isEmpty())
            return -1;
        return app.exec();
    

    My app class which is responsible for clearing cache and reloading qml..

    class App : public QObject
    {
        Q_OBJECT
    public:
        App( QObject* i_parent = nullptr );
        ~App();
    
        Q_INVOKABLE void load_qml();
        void set_engine( QQmlApplicationEngine* i_engine ){ m_engine = i_engine; }
    
    private:
        QQmlApplicationEngine* m_engine;
        QString m_qmlqrc_file;
    };
    

    and app.cpp

    #include "app.hpp"
    #include <QFileInfo>
    #include <QFileSelector>
    
    App::App( QObject* i_parent ) : QObject( i_parent )
    {
        m_qmlqrc_file = QString(QRC_SOURCE_PATH) + "qml.qrc";
    }
    
    App::~App(){}
    
    void App::load_qml()
    {
        std::cout << " here load qml " << std::endl;
        m_engine->clearComponentCache();
        std::cout << " m engine cleaned " << std::endl;
        std::cout << " loading " << QFileInfo(m_qmlqrc_file).absolutePath().toStdString() << "/main.qml" << std::endl;
        QFileSelector selector;
       // Q_CLEANUP_RESOURCE(qml);
      //  Q_INIT_RESOURCE(qml);
        QUrl source ( selector.select(
            QFileInfo(m_qmlqrc_file).absolutePath() + "/main.qml"
            )
        );
        // QUrl source ( QFileInfo("qrc:/main.qml").absoluteFilePath());
        m_engine->load(source);
    
    }
    

    Only the things that are at the root of qrc are being reloaded correctly at runtime (here only main.qml is reloaded, changing something in Foo.qml has no effect).
    But if I change my qml file and qml.qrc to look like this :

    <RCC>
        <qresource prefix="/">
            <file alias="main.qml">./main.qml</file>
            <file alias="Foo.qml">./Foo.qml</file>
        </qresource>
    </RCC>
    
    

    Then the changes in Foo.qml are picked up at runtime.
    I don't understand what is happening and how can I get qml to reload while running the app but still keeping my qml.qrc (and files) organized as before. Obviously my project is bigger than that and having all my qml files in one place is not an option.

    Any help would be greatly appreciated !

    ODБOïO 1 Reply Last reply
    1
    • EmilieGE EmilieG

      Hi all,

      I've spend 2hours trying to reload my QML within my running application.. with no luck.!
      I just want to have a hot key so that I can decide when developing when to reload everything.
      I found a few ways of doing it (here and here ) but nothing worked properly, I manage to get some components being reloaded on the fly properly but not everything...

      I nailed it down to a small failure case.
      I'm using a qrc file to manage all my qml. and ressource in my qml.qrc are handled as follow:

      <RCC>
          <qresource prefix="/">
              <file alias="main.qml">./main.qml</file>
          </qresource>
          <qresource prefix="/Bar">
              <file alias="Foo.qml">./Foo.qml</file>
          </qresource>
      </RCC>
      
      

      My main.qml looks like this

      import "qrc:/Bar"
      ApplicationWindow {
          id: root
          visible: true
          width: 1920
          height: 1080
          Foo {
            anchors.fill: parent
          }
      }
      

      My main.cpp

      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
          QQmlApplicationEngine engine;
          App _app;
          engine.rootContext()->setContextProperty(QStringLiteral("app"), &_app);
          _app.set_engine(&engine);
          QUrl source (QStringLiteral("qrc:/main.qml"));
          engine.load(source);
          if (engine.rootObjects().isEmpty())
              return -1;
          return app.exec();
      

      My app class which is responsible for clearing cache and reloading qml..

      class App : public QObject
      {
          Q_OBJECT
      public:
          App( QObject* i_parent = nullptr );
          ~App();
      
          Q_INVOKABLE void load_qml();
          void set_engine( QQmlApplicationEngine* i_engine ){ m_engine = i_engine; }
      
      private:
          QQmlApplicationEngine* m_engine;
          QString m_qmlqrc_file;
      };
      

      and app.cpp

      #include "app.hpp"
      #include <QFileInfo>
      #include <QFileSelector>
      
      App::App( QObject* i_parent ) : QObject( i_parent )
      {
          m_qmlqrc_file = QString(QRC_SOURCE_PATH) + "qml.qrc";
      }
      
      App::~App(){}
      
      void App::load_qml()
      {
          std::cout << " here load qml " << std::endl;
          m_engine->clearComponentCache();
          std::cout << " m engine cleaned " << std::endl;
          std::cout << " loading " << QFileInfo(m_qmlqrc_file).absolutePath().toStdString() << "/main.qml" << std::endl;
          QFileSelector selector;
         // Q_CLEANUP_RESOURCE(qml);
        //  Q_INIT_RESOURCE(qml);
          QUrl source ( selector.select(
              QFileInfo(m_qmlqrc_file).absolutePath() + "/main.qml"
              )
          );
          // QUrl source ( QFileInfo("qrc:/main.qml").absoluteFilePath());
          m_engine->load(source);
      
      }
      

      Only the things that are at the root of qrc are being reloaded correctly at runtime (here only main.qml is reloaded, changing something in Foo.qml has no effect).
      But if I change my qml file and qml.qrc to look like this :

      <RCC>
          <qresource prefix="/">
              <file alias="main.qml">./main.qml</file>
              <file alias="Foo.qml">./Foo.qml</file>
          </qresource>
      </RCC>
      
      

      Then the changes in Foo.qml are picked up at runtime.
      I don't understand what is happening and how can I get qml to reload while running the app but still keeping my qml.qrc (and files) organized as before. Obviously my project is bigger than that and having all my qml files in one place is not an option.

      Any help would be greatly appreciated !

      ODБOïO Offline
      ODБOïO Offline
      ODБOï
      wrote on last edited by
      #2

      @EmilieG hi
      you might find this interesting

      1 Reply Last reply
      0
      • EmilieGE Offline
        EmilieGE Offline
        EmilieG
        wrote on last edited by
        #3

        Thanks, I will give it a try but I would rather not use another tool if I can.

        1 Reply Last reply
        0
        • EmilieGE Offline
          EmilieGE Offline
          EmilieG
          wrote on last edited by
          #4

          After trying qmllive doesn't seem to handle properly my .qrc file..

          J.HilkJ KroMignonK 2 Replies Last reply
          0
          • EmilieGE EmilieG

            After trying qmllive doesn't seem to handle properly my .qrc file..

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #5

            @EmilieG you're doing something strange, why are you importing bar this way

            import "qrc:/Bar"
            

            instead of

            import "Bar"
            

            that removes the explicit dependency to the qrc file and should help


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            1 Reply Last reply
            0
            • EmilieGE EmilieG

              After trying qmllive doesn't seem to handle properly my .qrc file..

              KroMignonK Offline
              KroMignonK Offline
              KroMignon
              wrote on last edited by
              #6

              @EmilieG said in Hot reloading QML with QRC file.:

              After trying qmllive doesn't seem to handle properly my .qrc file..

              As far as I know, live update only works for QML outside from resource file.
              If QML is in resource file, it is "frozen". You have to load QML from file system.

              It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

              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