[solved]QQmlApplicationEngine: Moving from 5.2 to 5.3



  • Hi

    I am updating my little QtQuick application from 5.2 to 5.3. I noticed that the main.cpp looks a bit different now with the QQmlApplicationEngine and that the QQuickWindow has disappeared.
    My main.cpp in 5.2 looked like the following:

    @
    #include <QtQml>
    #include <qtquick2applicationviewer.h>

    #include "XXX.h"

    // switch native or generic // if using native add QT+=widget in pro file
    #define USE_NATIVE_LOOK 0

    #if USE_NATIVE_LOOK
    #include <QtWidgets/QApplication>
    #define Application QApplication
    #else
    #include <QtGui/QGuiApplication>
    #define Application QGuiApplication
    #endif

    int main(int argc, char *argv[])
    {
    Application app(argc, argv);

    qmlRegisterType<XXX>("XXX", 1, 0, "XXX");
    
    QQmlApplicationEngine engine;
    engine.load(QUrl("qml/qmlEngine08/main.qml"));
    QObject *topLevel = engine.rootObjects().value(0);
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
    if ( !window ) {
        qWarning("Error: Your root item has to be a Window.");
        return -1;
    }
    
    window->show();
    return app.exec&#40;&#41;;
    

    }
    @

    what i have so far with in the new 5.3 version:

    @
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>

    #include <QtQml>

    #include "XXX.h"

    int main(int argc, char *argv[])
    {
    QGuiApplication app(argc, argv);

    qmlRegisterType<XXX>("XXX", 1, 0, "XXX");
    
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    
    return app.exec(&#41;;
    

    }
    @

    The application compiles without any errors, but the GUI is not shown. What am I missing?
    Thank you for any help!


  • Moderators

    You are missing the QQuickWindow part, obviously ;-) You are loading the QML code into the engine, but not displaying it.

    BTW. I recommend using QQuickView as a better alternative. Requires less code to be written.



  • Alright :)
    I was a bit confused by the fact that if you create a new QtQuick project, the QQuickWindow part is not there anymore by default, yet it diplays the GUI. So why does it work without a QQuickView if you just launch a newly created project?

    I adapted the code as follows (it works now, thank you!):
    @
    int main(int argc, char *argv[])
    {
    Application app(argc, argv);

    qmlRegisterType<DownloadManager>("DownloadManager", 1, 0, "DownloadManager");
    
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    
    QObject *topLevel = engine.rootObjects().value(0);
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
    if ( !window ) {
        qWarning("Error: Your root item has to be a Window.");
        return -1;
    }
    
    window->show();
    return app.exec&#40;&#41;;
    

    }
    @

    What do you mean by "QQuickView is the better alternative"? I do require the engine for the C++ Classes, right?
    Sorry, I don't really have the overview yet :)
    Thank you for your superfast help anyway!!!


  • Moderators

    In QQuickView, the engine is built-in, you only need to specify the input file path and call show(), which is why I use it in my projects. But your approach is also entirely valid.



  • I see! I think I am slowly getting it...so a basically have three options:

    @
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>

    // option 2:
    //#include <QQuickWindow>

    // option 3:
    //#include <QQuickView>

    #include <QtQml>

    #include "DownloadManager.h"

    // switch native or generic // if using native add QT+=widget in pro file
    #define USE_NATIVE_LOOK 0

    #if USE_NATIVE_LOOK
    #include <QtWidgets/QApplication>
    #define Application QApplication
    #else
    #include <QtGui/QGuiApplication>
    #define Application QGuiApplication
    #endif

    int main(int argc, char *argv[])
    {
    Application app(argc, argv);

    qmlRegisterType<DownloadManager>("DownloadManager", 1, 0, "DownloadManager");
    
    // option 1 (easiest):
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    // note: ApplicationWindow must explicitly be set to: "visible: true"
    
    // option 2:
    

    // QQmlApplicationEngine engine;
    // engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    // QObject *topLevel = engine.rootObjects().value(0);
    // QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
    // if ( !window ) {
    // qWarning("Error: Your root item has to be a Window.");
    // return -1;
    // }
    // window->show();

    // option 3: only works if main.qml is NOT ApplicationWindow
    

    // QQuickView *view = new QQuickView;
    // view->setSource(QUrl(QStringLiteral("qrc:///main.qml")));
    // view->show();

    return app.exec&#40;&#41;;
    

    }

    @

    As my main.qml uses an ApplicationWindow, I can't use QQuickView. For option 1, it turned out, that is crucial to set "visible: true" in the ApplicationWindow. Some more info can be found "here":http://www.qtcentre.org/threads/54649-ApplicationWindow-as-root-object-result-in-error, "here":http://stackoverflow.com/questions/18506784/qml-and-c-with-qt-quick-2-application and "here":http://stackoverflow.com/questions/19159928/how-to-change-title-of-a-qtquick-2-window.

    Is that correct?


  • Moderators

    Nice, thanks for thorough explanation, it also helped me learn something :-D



  • Thank you guys that was really helpful.


Log in to reply
 

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