Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Unable to connect c++ and QML (share values of c++ variabls, and read values of QML and store into variables)



  • Hello, I'm really frustrated, because I spent the whole week only googling, and the most I managed to do is simply to run an empty qml project.
    the problem is that I want to integrate ROS into Qt, and for the graphics I need QtQuick. I've already done it in QtWidgets, but it seems like the QtQuick is a whole new process, and requires me to change the whole approach to interact with the UI.
    I'm really lost, because it seems like they are multiple ways to interact with the UI from c++ and multiple ways (at least 2, QApplicationEngine and QQuickView it seems). I imported my project from .qmlproject and it seems like only QQuickView works for me to run the UI.
    the problem is that when it comes to making a connection between c++ and qml, there is something at the middle that doesn't work, and the closest I got is this example I'll add below.
    I'm really really, lost.. all the examples I found on github are old, or use the QApplicationEngine.. which in any way i tried, doesn't seem to work (I either get a small blank screen, or it crashes right away)

    now, I am very close to making some connection to QML from c++ but the moment I need to import the backend class, using the QmlRegisterType it seems to simply not find the package. no matter what I did.

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQuickView>
    #include <QQmlContext>
    
    #include <backend.h>
    
    int main(int argc, char *argv[])
    {
    
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
    
        BackEnd backend;
    
    
        QQuickView view;
        view.engine()->addImportPath("qrc:/qml/imports");
        view.setSource(QUrl("qrc:/qml/Screen01.ui.qml"));
        if (!view.errors().isEmpty())
            return -1;
    
        qmlRegisterType<BackEnd>("BackendConnection", 1, 0, "backend");
    
        view.show();
        return app.exec();
    }
    
    

    backend.h

    #ifndef BACKEND_H
    #define BACKEND_H
    
    #include <QObject>
    
    class BackEnd : public QObject
    {
        Q_OBJECT
    
        Q_PROPERTY(QString leftGaugeVal READ leftGaugeVal WRITE setLeftGaugeVal NOTIFY leftGaugeValChanged)
    
        QString m_leftGaugeVal;
    
    public:
        explicit BackEnd(QObject *parent = nullptr);
    
        QString leftGaugeVal() const
        {
            return m_leftGaugeVal;
        }
    
    public slots:
        void setLeftGaugeVal(QString leftGaugeVal)
        {
            if (m_leftGaugeVal == leftGaugeVal)
                return;
    
            m_leftGaugeVal = leftGaugeVal;
            emit leftGaugeValChanged(m_leftGaugeVal);
        }
    
    signals:
    
        void leftGaugeValChanged(QString leftGaugeVal);
    };
    
    #endif // BACKEND_H
    
    

    backend.cpp

    #include "backend.h"
    
    BackEnd::BackEnd(QObject *parent) : QObject(parent)
    {
    
    }
    
    
    

    I'll be honest, I saw somewhere on stackoverflow some guy used the widgets approach to run qml UI.. and I would really appreciate if someone got something similar and I could interact with items in QML using something similar to ui->Object->property->setValue();
    the closet of a solution I can to this, the better.

    Thanks in advance, i'm really lost, I read too many stackoverflow and Qt Forums.. and everytime something small makes me lose the solution.

    PS: I tried to copy this solution he added as an answer (this answer)
    I tried with a base class of QQuickItem but got the same error, so I tried the QObject class. but got the same..



  • Hi,

    you need to set the context property.

    view.rootContext()->setContextProperty("backend", &backend);

    Than you can access the leftGaugeVal property of backend in your qml code with backend.leftGaugeVal

    for example:

    Label {
    id: lbl
    text: backend.leftGaugeVal
    }

    will bind the backend.leftGaugeVal to the label text property.



  • Hi,

    you need to set the context property.

    view.rootContext()->setContextProperty("backend", &backend);

    Than you can access the leftGaugeVal property of backend in your qml code with backend.leftGaugeVal

    for example:

    Label {
    id: lbl
    text: backend.leftGaugeVal
    }

    will bind the backend.leftGaugeVal to the label text property.



  • oh my god, thank you!
    I had barely any hope to get an answer, but I checked anyway! you made my day much much brighter. I was fighting with this for about 2 weeks now!
    Its great, I do not need to use "import backend" and simply use the backend.LeftGaugeVal
    and additionaly, I'm changing it simply by calling the "setLeftgaugeVal" I made from the Q_PROPERTY from C++
    It really solved my issue, and made it really straightforward for me.
    Thanks!


Log in to reply