Periodically update data in QML [Solved?]
-
I make minimal example project
hub.h#ifndef Hub_H #define Hub_H #include <QObject> #include <QMap> class Hub : public QObject { Q_OBJECT Q_PROPERTY(QList<double> channelData READ channelData WRITE setChannelData NOTIFY channelDataChanged) public: explicit Hub(QObject *parent = nullptr) { m_channelData=QList<double>({1,2,3,4,5,6,7,8}); } void setChannelData(QList<double> channelData) { m_channelData = channelData; //set current data value } QList<double> channelData() // return current data list { return m_channelData; } private: QList<double> m_channelData; // list of current datas signals: void channelDataChanged(); }; #endif // Hub_H
main.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include <QTimer> #include <QtDebug> #include <QRandomGenerator> #include "Hub/hub.h" void setItem(QQmlApplicationEngine *pEngine); Hub channel_1; int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("ch", &channel_1); engine.load(QUrl(QStringLiteral("qrc:/QML/main.qml"))); if (engine.rootObjects().isEmpty()) return -1; QTimer timer; QObject::connect(&timer, &QTimer::timeout, [&engine]() { setItem(&engine); }); timer.start(5000); return app.exec(); } void setItem(QQmlApplicationEngine *pEngine) { QList<double> temp; for (int i=0;i<8;i++) { temp.append(QRandomGenerator::global()->bounded(90, 110)); } channel_1.setChannelData(temp); qWarning() << "/********************************************************/"; qWarning() << "Data = " << channel_1.channelData(); }
main.qml
import QtQuick 2.0 Window { id: root width: 400 height: 150 visible: true Rectangle { id: currentHub color: "green" border.color: Qt.lighter(color) anchors.fill: parent Row { height: currentHub.height width: currentHub.width Repeater { id: hub_id model: 8 Rectangle { id: oneChartBar anchors.bottom: parent.bottom color: "red" height: ch.channelData[index] === 0?1:ch.channelData[index] width: currentHub.width/8 border.width: 1 border.color: Qt.lighter(color) Text { id: showchannel anchors.horizontalCenter: oneChartBar.horizontalCenter anchors.bottom: oneChartBar.bottom text: qsTr("%1").arg(index+1) color: "white" } } } } } Timer { interval: 500; running: true; repeat: true onTriggered: ch.channelData() } }
Idea is -
channelData is QList <double> (size 8). This is data from 8 sensors. Period of sensor update may changing (not realized in example). On QML side it read initial values for channelData and show as rectangle chart. I want periodically read channelData Qlist values and update charts.
ButTimer { interval: 500; running: true; repeat: true onTriggered: ch.channelData() }
get error
qrc:/QML/main.qml:40: TypeError: Property 'channelData' of object Hub(0x5555f0d2f4c0) is not a function
qrc:/QML/main.qml:40: TypeError: Type errorP.S.
While writing a post I get solution
Timer in QML must beTimer { interval: 500; running: true; repeat: true onTriggered: ch.channelDataChanged() }
If any body have better solution please add it here.
-
@Kuzma30 said in Periodically update data in QML [Solved?]:
channelData
channelData is Q_PROPERTY. You can directly use it. channelData() method is not Q_INVOKABLE or SLOT. You can't cal it. channelDataChanged() is a signal. No point in calling it.
Summary access channelData property directly like ch.channelData.
-
@Kuzma30 said in Periodically update data in QML [Solved?]:
void setChannelData(QList<double> channelData) { m_channelData = channelData; //set current data value }
No timer is needed.
void setChannelData(QList<double> channelData) { if (channelData.size() != m_channelData.size() /*or something like contents changed*/ ) { m_channelData = channelData; //set current data value emit channelDataChanged(); //to tell qml things have changed for update } }