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. Periodically update data in QML [Solved?]
Forum Updated to NodeBB v4.3 + New Features

Periodically update data in QML [Solved?]

Scheduled Pinned Locked Moved Solved QML and Qt Quick
4 Posts 3 Posters 476 Views
  • 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.
  • K Offline
    K Offline
    Kuzma30
    wrote on last edited by
    #1

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

     Timer {
            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 error

    P.S.
    While writing a post I get solution

    Timer in QML must be

        Timer {
            interval: 500; running: true; repeat: true
            onTriggered: ch.channelDataChanged()
        }
    

    If any body have better solution please add it here.

    1 Reply Last reply
    0
    • dheerendraD Offline
      dheerendraD Offline
      dheerendra
      Qt Champions 2022
      wrote on last edited by
      #2

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

      Dheerendra
      @Community Service
      Certified Qt Specialist
      http://www.pthinks.com

      1 Reply Last reply
      1
      • K Offline
        K Offline
        Kuzma30
        wrote on last edited by
        #3

        I use it directly. But without Timer it doesn't update charts.

                     Repeater {
        ...
                             height: ch.channelData[index] === 0?1:ch.channelData[index]
        
        1 Reply Last reply
        0
        • JoeCFDJ Offline
          JoeCFDJ Offline
          JoeCFD
          wrote on last edited by JoeCFD
          #4

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