Scope of QML objects - adding data to a ChartView from another QML object
-
I need some pointers on how to proceed with adding data to a ChartView that is on one of the tabs of a TabView. I'm assuming that I don't fully grasp the scoping of QML objects.
The scope.qml file references a ValueSource QML object that collects data at set intervals using a Timer. This data needs to be fed to a ChartView on a tab. Unfortunately I'm unable to feed the data from the ValueSource object to the ChartView object. I'm using:
lineSeries.append(i, Math.random());
In reality the data would be fetched from a webserver but for the sake of simplicity I'm using random numbers instead. The data fetched from the webserver will be fed to several gauges and charts on different tabs, this is why the value source is in a separate qml file.
The error message is:
qrc:/qml/ValueSource.qml:15: ReferenceError: lineSeries is not defined
Using the id of the chart or lineseries also doesn't work.
I'm assuming that I'm making some basic mistake in referencing but cannot find any examples on how to proceed. How should I properly reference the lineseries?
TEMPLATE = app TARGET = scope INCLUDEPATH += . QT += quick QT += charts QT += widgets SOURCES += \ main.cpp RESOURCES += \ scope.qrc OTHER_FILES += \ qml/scope.qml \ qml/ValueSource.qml\ qml/Settings.qml target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols/extras/scope INSTALLS += target DISTFILES += \ qml/Settings.qml
main.cpp
#include <QtGui/QGuiApplication> #include <QtQml/QQmlApplicationEngine> #include <QtGui/QFont> #include <QtGui/QFontDatabase> #include <QApplication> int main(int argc, char *argv[]) { QApplication app(argc, argv); QQmlApplicationEngine engine(QUrl("qrc:/qml/scope.qml")); if (engine.rootObjects().isEmpty()) return -1; return app.exec(); }
scope.qml
import QtQuick 2.2 import QtQuick.Window 2.1 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Extras 1.4 Window { id: root visible: true width: 1024 height: 600 title: "Scope" ValueSource { id: valueSource } TabView { id: myTabView anchors.fill: parent Tab { id: myTab title: "Graph" Chart { id: myChart; visible: true } } } }
ValueSource.qml
import QtQuick 2.2 Item { id: valueSource Timer { interval: 1000; running: true; repeat: true onTriggered: getData() } function getData() { // get some data from a webserver // for the sake of simplicity I'm adding random data as if these come from the webserver // update graph accordingly lineSeries.append(i, Math.random()); } }
Chart.qml
import QtQuick 2.0 import QtQuick.LocalStorage 2.0 import QtQuick.Controls 1.4 import QtQuick.Extras 1.4 import QtCharts 2.0 Item { id: itm ChartView { id: chartView title: "Webserver data" width: 500 height: 500 legend.alignment: Qt.AlignTop animationOptions: ChartView.SeriesAnimations antialiasing: true ValueAxis { id: xAxis min: 0 max: 10 } ValueAxis { id: yAxis min: 0 max: 10 } LineSeries { id: lineSeries name: "LineSeries" XYPoint { x: 0; y: 0 } XYPoint { x: 1.1; y: 2.1 } XYPoint { x: 1.9; y: 3.3 } XYPoint { x: 2.1; y: 2.1 } XYPoint { x: 2.9; y: 4.9 } XYPoint { x: 3.4; y: 3.0 } XYPoint { x: 4.1; y: 3.3 } } } }
-
@AimedSquid Add a component scope to each of your QML for eg.
Chart.qml
:Item { id: itm property alias _lineSeries: lineSeries ... }
Now
_lineSeries
will be accessible inroot
provided you get access to the tab using getTab and then toTab
's item using item.In the same way add component scoping wherever required.
-
Thanks very much p3c0. The revised code for ValueSource.qml:
import QtQuick 2.2 Item { id: valueSource property int cntr : 0 Timer { interval: 1000; running: true; repeat: true onTriggered: getData() } function getData() { // get some data from a webserver // for the sake of simplicity I'm adding random data as if these come from the webserver // update graph accordingly var lineSeries = tabView.getTab(0).item._lineSeries lineSeries.append(cntr,Math.random()) if (cntr>3) { lineSeries.axisX.max ++ lineSeries.axisX.min ++ } cntr++ } }
Revised code for Chart.qml:
import QtQuick 2.0 import QtQuick.LocalStorage 2.0 import QtQuick.Controls 1.4 import QtQuick.Extras 1.4 import QtCharts 2.0 Item { id: itm property alias _lineSeries: lineSeries ChartView { id: chartView title: "Webserver data" width: 500 height: 500 legend.alignment: Qt.AlignTop animationOptions: ChartView.SeriesAnimations antialiasing: true ValueAxis { id: xAxis min: 0 max: 3 } ValueAxis { id: yAxis min: 0 max: 1 } LineSeries { id: lineSeries name: "LineSeries" axisX: xAxis axisY: yAxis } } }