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. Accessing Qt Charts with QDateTimeAxis in QML from C++
QtWS25 Last Chance

Accessing Qt Charts with QDateTimeAxis in QML from C++

Scheduled Pinned Locked Moved Solved QML and Qt Quick
4 Posts 1 Posters 2.1k 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.
  • 5 Offline
    5 Offline
    54474N4
    wrote on last edited by
    #1

    I have a problem with Qt charts and with QDateTimeAxis. Inserted data won't display properly, when series is edited from C++ class. In main.qml I have only ChartView which is edited from C++ class DataHandler. DataHandler generates random data every second with current time stamp and edits the series in chart correspondigly. Also chart x-axis is edited dynamically. Changing the QDateTimeAxis to ValueAxis fixes the problem, but then the data time won't be in readable format in chart.

    Here is main.cpp

    #include <QGuiApplication>
    #include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlEngine>
    #include <QQmlContext>
    #include <QQmlComponent>
    #include "datahandler.h"
    
    int main(int argc, char *argv[])
    {
    
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QApplication app(argc, argv);
        QQmlApplicationEngine engine;
     
        QQmlComponent component(&engine, QUrl(QLatin1String("qrc:/main.qml")));
        QObject *object = component.create();
    
        QScopedPointer<DataHandler> datahandler(new DataHandler(object));
        engine.rootContext()->setContextProperty("datahandler", datahandler.data());
    
        return app.exec();
    }
    

    Here is datahandler.h

    #ifndef DATAHANDLER_H
    #define DATAHANDLER_H
    #include <QObject>
    #include <QtCharts>
    
    QT_CHARTS_USE_NAMESPACE
    
    class DataHandler : public QObject
    {
        Q_OBJECT
    
    public:
        DataHandler(QObject* object, QObject *parent = 0);
        ~DataHandler();
    
    private:
        QTimer* m_timer;
        QObject* m_object;
        QObject* m_chart;
        QVector<QPointF> m_data1, m_data2;
    
    public slots:
        void addValues();
    
    };
    
    #endif // DATAHANDLER_H
    
    

    ...and datahandler.cpp

    #include "datahandler.h"
    #include <QObject>
    #include <QTimer>
    #include <QDateTime>
    #include <QDebug>
    
    
    DataHandler::DataHandler(QObject* object, QObject *parent)
    {
        m_timer = new QTimer();
        m_object = object;
        connect(m_timer, &QTimer::timeout, this, &DataHandler::addValues);
        m_chart = m_object->findChild<QObject*>("chart");
        m_timer->start(1000);
    
    }
    
    DataHandler::~DataHandler(){
    
    }
    
    void DataHandler::addValues(){
    
        if(m_chart){
            //Generate the data
            m_data1.append(QPointF(QDateTime::currentMSecsSinceEpoch(), qrand() % 100));
            m_data2.append(QPointF(QDateTime::currentMSecsSinceEpoch(), qrand() % 100));
            QAbstractSeries *series1;
            QAbstractSeries *series2;
            QAbstractAxis *xAxis;
            //Fetch the series and x-axis from QML
            QMetaObject::invokeMethod(m_chart, "series", Qt::AutoConnection, Q_RETURN_ARG(QAbstractSeries*, series1), Q_ARG(int, 0));
            QMetaObject::invokeMethod(m_chart, "series", Qt::AutoConnection, Q_RETURN_ARG(QAbstractSeries*, series2), Q_ARG(int, 1));
            QMetaObject::invokeMethod(m_chart, "axisX", Qt::AutoConnection, Q_RETURN_ARG(QAbstractAxis*, xAxis));
            //Cast the series and axis to proper form
            QXYSeries* xyseries1 = static_cast<QXYSeries *>(series1);
            QXYSeries* xyseries2 = static_cast<QXYSeries *>(series2);
            QDateTimeAxis* dateTimeAxis = static_cast<QDateTimeAxis *>(xAxis);
    
            //set the new values to series and axises
            xyseries1->replace(m_data1);
            xyseries2->replace(m_data2);
            dateTimeAxis->setMax(QDateTime::fromMSecsSinceEpoch(m_data1.last().x()));
            dateTimeAxis->setMin(QDateTime::fromMSecsSinceEpoch(m_data1.first().x()));
    
        }
    }
    
    

    Here is main.qml

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.3
    import QtCharts 2.0
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        ChartView{
            id: chart
            objectName: "chart"
            antialiasing: true
            legend.visible: false
            width: parent.width
            height: parent.height
            anchors.fill: parent
            theme: ChartView.ChartThemeBlueCerulean
    
            ValueAxis{
                id:axisY
                min:0
                max:100
            }
            DateTimeAxis{
                id:dateTime
                format: "hh:mm:ss"
                tickCount: 5
            }
    
            LineSeries{
                id:series1
                objectName: "series1"
                axisX: dateTime
                axisY: axisY
                useOpenGL: true
            }
    
            LineSeries{
                id: series2
                objectName: "series2"
                axisX: dateTime
                axisY: axisY
                useOpenGL: true
            }
        }
    }
    
    

    and ChartTest.pro file

    QT += qml quick widgets charts
    
    CONFIG += c++11
    
    SOURCES += main.cpp \
        datahandler.cpp
    
    RESOURCES += qml.qrc
    
    # Additional import path used to resolve QML modules in Qt Creator's code model
    QML_IMPORT_PATH =
    
    # Additional import path used to resolve QML modules just for Qt Quick Designer
    QML_DESIGNER_IMPORT_PATH =
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which as been marked deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    HEADERS += \
        datahandler.h
    
    
    1 Reply Last reply
    0
    • 5 Offline
      5 Offline
      54474N4
      wrote on last edited by
      #2

      I got the program working, by deleting and generating new series every time the chart update is required. First I delete and generate new series in QML and then call the addValues() function in C++ side. This solves the problem, but does not change the fact that there seems to be something wrong with the QDateTimeSeries update.

      1 Reply Last reply
      0
      • 5 Offline
        5 Offline
        54474N4
        wrote on last edited by
        #3

        I noticed that the actual cause of the problem is in LineSeries useOpenGL property. When OpenGL is on, the series won't update properly. After turnign OpenGL off, everything works just fine.

        5 1 Reply Last reply
        0
        • 5 54474N4

          I noticed that the actual cause of the problem is in LineSeries useOpenGL property. When OpenGL is on, the series won't update properly. After turnign OpenGL off, everything works just fine.

          5 Offline
          5 Offline
          54474N4
          wrote on last edited by
          #4

          @54474N4
          There seems to be QT bug report about the issue:
          https://bugreports.qt.io/browse/QTBUG-59674?jql=text ~ "OpenGL double float"

          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