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

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?

    scope.pro

    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 }
            }
        }
    }
    

  • Moderators

    @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 in root provided you get access to the tab using getTab and then to Tab'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
            }
        }
    }
    

Log in to reply