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

C++ updating data to QML



  • Hi,

    I've been searching for this issue for a while now, at the moment I'm more confused than ever:

    Issue:

    Display data in QML, that is being collected with C++, from the OS, updated in timed intervals

    • OS: GNU/Linux
    • Qt5 and QML

    So far I have managed to obtain the following:

    • C++ invokes the wanted system binary and collects the output
    • I'm using a QTimer to do this every 1000msec so the variable gets updated in C++
    • main.cpp has a setContextProperty definition, so that main.qml can reach the C++ variable

    So I'm able to use QML to reach the variable value in C++ and display/format it, but I'm not being able to refresh/update the data on QML. I'm only getting the first hit.

    I know that C++ QTimer is working because I've added a qDebug definition which shows the updated data, every second, at the console log.

    I will try to publish the code, however what would be the best way to achieve the intented result?

    I've also considered inverting my reasoning: use QML to invoke C++on demand, when needed, and have the timer on the QML side - didn't work...

    Thanks in advance



  • Is there any reason the variable couldn't be a property on a QObject with a NOTIFY signal (emit when you collect new data) on the C++ side? Then just have the QML bind to that property and things should just work.



  • I had an similar problem.

    See my post: http://qt-project.org/forums/viewthread/23449/#109214

    I found the solution in "Dokumentation":http://qt-project.org/doc/qt-5.0/qtcore/queuedcustomtype.html

    The example is Widgetbased, but it's allso working with qml.



  • Thank you both for your input, I've been at it for a while and I decided to start from scratch:

    This example attemps the following:

    C++

    • Clock has the task of attributing a random value to a variable

    • main has a Timer which invokes the function count() every second, generating a new random

    • each execution is sent to the console log

    • main has a property binding (hopefully that's the name) which attempts to expose the recurrent value to QML

    • QML has its own timer, with which I'd be hoping to have the C++ value refreshed (maybe not needed, the intent would be to make sure QML refreshed the variable - and a QML-own counter just to show activity)

    • the objective is to display the same randoms show in the console logs (from C++) on the white canvas from QML.

    Quite possibly my notions may still be off as I'm learning, so I'm taking your given help in trying to get there.

    Hopefully I will get a proper example working and when I do, I will update the code here!

    Many thanks!

    Using Qt Creator, I created a new project "Qt Quick 2 Application (Built-in Elements)

    Headers:

    clock.h

    @#ifndef CLOCK_H
    #define CLOCK_H

    #include <QObject>

    class Clock : public QObject
    {
    Q_OBJECT

    public:
    explicit Clock(QObject *parent = 0);

    signals:
    void counterUpdated();

    public slots:
    void count();

    };

    #endif // TIMER_H
    @

    clock.cpp

    @#include "clock.h"
    #include <QDebug>

    Clock::Clock(QObject *parent) :
    QObject(parent)
    {
    }

    void Clock::count(){
    long plus = random();
    qDebug() << plus;
    //emit counterUpdated();
    }
    @

    main.cpp

    @#include <QtGui/QGuiApplication>
    #include "qtquick2applicationviewer.h"
    #include <QTimer>
    #include <clock.h>
    #include <QDebug>
    #include <QQmlContext>
    #include <QObject>

    int main(int argc, char *argv[])
    {
    QString randomitum;
    QGuiApplication app(argc, argv);
    QtQuick2ApplicationViewer viewer;
    Clock *tintin = new Clock;
    QTimer *tim = new QTimer;
    QObject::connect(tim,SIGNAL(timeout()),tintin,SLOT(count()));
    tim->start(1000);

    viewer.rootContext()->setContextProperty("qmlCounter", randomitum);
    viewer.setMainQmlFile&#40;QStringLiteral("qml/fringe/main.qml"&#41;);
    viewer.showExpanded();
    
    return app.exec();
    

    }
    @

    main.qml

    @import QtQuick 2.0

    Rectangle {
    width: 360
    height: 360
    property int flip : 0
    Text {
    id: textum
    anchors.centerIn: parent
    }

    Timer {
        interval: 1000; running: true; repeat: true
        onTriggered: { flip = flip +1; textum.text = qmlCounter + " : " + flip }
    }
    
    MouseArea {
        anchors.fill: parent
        onClicked: {
            Qt.quit();
        }
    }
    

    }
    @



  • Do N3Roaster said. From "http://qt-project.org/doc/qt-5.0/qtqml/qtqml-cppintegration-exposecppattributes.html":http://qt-project.org/doc/qt-5.0/qtqml/qtqml-cppintegration-exposecppattributes.html

    For maximum interoperability with QML, any property that is writable should have an associated NOTIFY signal that is emitted whenever the property value has changed.


Log in to reply