Qt World Summit: Submit your Presentation

QQmlComponent: Component is not ready

  • Hi all,

    So before you flame me for not doing my research, I have looked through the Qt Forums & Stack Overflow to see how other people have dealt with this issue. Unfortunately, my situation seems to be slightly more complicated.

    Like the post title says, I am getting a "QQmlComponent: Component is not ready" error.


    #include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include <QFile>
    #include <QDebug>
    #include <QQmlComponent>
    #include <QUrl>
    #include <QStringLiteral>
    #include "datamodel.h"
    #include "datamodule.h"
    #include "datapiece.h"
    int main(int argc, char *argv[])
        QApplication app(argc, argv);
        QQmlApplicationEngine engine;
        //    qDebug() << comp.errorString();
        //    qDebug() << comp.status();
        //    qDebug() << comp.progress();
        QQmlContext * context = engine.rootContext();
        DataModel model("C:\\Users\\AMcFarlane\\Qt\\projects\\UiTest\\mock_loader_test");
        if (engine.rootObjects().isEmpty())
            return -1;
        QQmlComponent comp(&engine,QUrl("C:\\Users\\AMcFarlane\\Qt\\projects\\UiTest\\Display0.qml"));
        QFile file("C:\\Users\\AMcFarlane\\Qt\\projects\\UiTest\\Display0.qml");
        qDebug() << "path correctness: " <<file.exists();
        qDebug() << "status: "<<comp.status()<<endl<<"progress: "<<comp.progress();
        QObject *summaryPage = comp.create(context);
        return app.exec();

    The output from those qDebug statements near the bottom looks like this:

    path correctness:  true
    status:  QQmlComponent::Status(Loading) 
    progress:  0
    QQmlComponent: Component is not ready

    So the filepath is correct. According to the compiler, my component is "Loading", but as you can see, progress is at 0%.

    I have also tried calling comp.create() with & without the context argument.

    That being said, I have 2 suspicions.

    I am thinking that there could be a problem with my execution flow. I tried rearranging things, putting the QQmlComponent instantiation before & after loading the engine and setting my context property, to no avail.

    Secondly, do I need to manually tell my program to wait until the QQmlComponent has loaded? I don't foresee this being true, as I feel like it really should not take long at all.

    I would really appreciate any ideas or possible suggestions. Thank you!

    EDIT: I included a while loop that IF the component is "loading", it waits until the component has loaded, regularly reporting progress. This resulted in a console full of zeros, and a crashed program.

  • @KillerSmath That was one of the first posts I came across in troubleshooting this.

    So, I did just solve it, but in a very peculiar manner.

    Initially when I tried to test the file path with QFile::exists(), it returned false when I instantiated the file with "qrc:/filename.qml" and return true when I instantiated with the full path instead.

    This led me to rely on using the full path when trying to instantiate the QQmlComponent, which turned out to be my problem.

    changing QQmlComponent comp(&engine,QUrl("C:\\Users\\AMcFarlane\\Qt\\projects\\UiTest\\Display0.qml"));

    to QQmlComponent comp(&engine,QUrl(QStringLiteral("qrc:/Display0.qml")));

    That seemed to fix the issue. So in retrospect, QFile & QUrl have slightly different tastes when it comes to file paths.

    NOTE: You can pass a QString to the QUrl, just as easily as a QStringLiteral. Both work.

  • @devDawg

    In memory, resources are represented by a tree of resource objects. The tree is automatically built at startup and used by QFile for resolving paths to resources. You can use a QDir initialized with ":/" to navigate through the resource tree from the root.

    So, you could use:

    QQmlComponent comp(&engine,QUrl("qrc:/Display0.qml"));
    QFile file(":/Display0.qml"); // acessing by resource tree

    NOTE: QStringLiteral is a optimization case, you can use QStringLiteral to avoid the implicit conversion between char* to QString and then copy the data.

    Qt Resource Documentation - Using resource in the application
    QStringLiteral Explanation