Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Scope of QML objects - adding data to a ChartView from another QML object
Qt 6.11 is out! See what's new in the release blog

Scope of QML objects - adding data to a ChartView from another QML object

Scheduled Pinned Locked Moved Solved QML and Qt Quick
3 Posts 2 Posters 2.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • AimedSquidA Offline
    AimedSquidA Offline
    AimedSquid
    wrote on last edited by
    #1

    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 }
            }
        }
    }
    
    1 Reply Last reply
    0
    • p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by p3c0
      #2

      @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.

      157

      1 Reply Last reply
      1
      • AimedSquidA Offline
        AimedSquidA Offline
        AimedSquid
        wrote on last edited by
        #3

        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
                }
            }
        }
        
        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved