c++qtqt5qt-creatorqtcharts

Dynamically updating QCharts on runtime using signals and slots


The below code is related to qchart example "Custom chart" in qt examples. I tried several different solutions but failed to understand or get a proper idea as a solution. I want to get my chart to update values on run time. so the chart values don't remain static but instead, they are dynamic. I want it to be signal & slot-based. (technically signal will be coming from another file including data but here for testing purposes I tried to use that push button as signal and slot but failed to understand how to do it). I tried it but nothing happens. I just don't know where I am missing it. Below is the code.

main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;

    w.show();
    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<windows.h>




MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
//  int foo [5] = { 8, 9, 10, 11, 120 };
//    for(int i=0;i <10; i++)
//    {
//        Sleep(1000);


    ui->setupUi(this);
    //![1]
        QLineSeries *series = new QLineSeries();
        *series << QPointF(0, 6) << QPointF(9, 4) << QPointF(15, 20) << QPointF(25, 12) << QPointF(29, 26);
        QChart *chart = new QChart();
        chart->legend()->hide();
        chart->addSeries(series);
    //![1]

    //![2]
        // Customize series
        QPen pen(QRgb(0xfdb157));
        pen.setWidth(5);
        series->setPen(pen);

        // Customize chart title
        QFont font;
        font.setPixelSize(18);
        chart->setTitleFont(font);
        chart->setTitleBrush(QBrush(Qt::white));
        chart->setTitle("Customchart example");

        // Customize chart background
        QLinearGradient backgroundGradient;
        backgroundGradient.setStart(QPointF(0, 0));
        backgroundGradient.setFinalStop(QPointF(0, 1));
        backgroundGradient.setColorAt(0.0, QRgb(0xd2d0d1));
        backgroundGradient.setColorAt(1.0, QRgb(0x4c4547));
        backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
        chart->setBackgroundBrush(backgroundGradient);

        // Customize plot area background
        QLinearGradient plotAreaGradient;
        plotAreaGradient.setStart(QPointF(0, 1));
        plotAreaGradient.setFinalStop(QPointF(1, 0));
        plotAreaGradient.setColorAt(0.0, QRgb(0x555555));
        plotAreaGradient.setColorAt(1.0, QRgb(0x55aa55));
        plotAreaGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
        chart->setPlotAreaBackgroundBrush(plotAreaGradient);
        chart->setPlotAreaBackgroundVisible(true);
    //![2]

    //![3]
        QCategoryAxis *axisX = new QCategoryAxis();
        QCategoryAxis *axisY = new QCategoryAxis();

        // Customize axis label font
        QFont labelsFont;
        labelsFont.setPixelSize(12);
        axisX->setLabelsFont(labelsFont);
        axisY->setLabelsFont(labelsFont);

        // Customize axis colors
        QPen axisPen(QRgb(0xd18952));
        axisPen.setWidth(2);
        axisX->setLinePen(axisPen);
        axisY->setLinePen(axisPen);

        // Customize axis label colors
        QBrush axisBrush(Qt::white);
        axisX->setLabelsBrush(axisBrush);
        axisY->setLabelsBrush(axisBrush);

        // Customize grid lines and shades
        axisX->setGridLineVisible(false);
        axisY->setGridLineVisible(false);
        axisY->setShadesPen(Qt::NoPen);
        axisY->setShadesBrush(QBrush(QColor(0x99, 0xcc, 0xcc, 0x55)));
        axisY->setShadesVisible(true);
    //![3]

    //![4]
    //
        axisX->append( "Monday", 0);
        axisX->append("Tuesday", 10);
        axisX->append("Wednesday", 15);
        axisX->append("Thursday", 20);
        axisX->append("Friday", 25);
        axisX->append("Saturday", 30);
        axisX->append("Sunday", 35);
        axisX->setRange(0, 35);


        axisY->append("Normal", 10);
        axisY->append("Yellow", 20);
        axisY->append("Red", 30);
        axisY->setRange(0, 30);

        chart->addAxis(axisX, Qt::AlignBottom);
        chart->addAxis(axisY, Qt::AlignLeft);
        series->attachAxis(axisX);
        series->attachAxis(axisY);
        QChartView *chartView = new QChartView(chart);
        chartView->setRenderHint(QPainter::Antialiasing);
        //stackoverflolwbelow
        QVBoxLayout *layout = new QVBoxLayout(ui->chartframe);
        layout->addWidget(chartView);



    //![4]
        QLCDNumber *lcd = new QLCDNumber;
        lcd->display(1501);
      //  lcd->setMinimumSize(250,100);
        //lcd->setParent(ui->lcdframe);
        QVBoxLayout *layoutLCD = new QVBoxLayout(ui->lcdframe);
        layoutLCD->addWidget(lcd);
    //![5]

        //stackoverflowabove
      //  chartView-> setParent(ui->chartframe);




    //![5]
    //!
    //!
//        MainWindow window;
//        window.setCentralWidget(chartView);

}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{

        qInfo() << "C++ Style Info Message";

        QLineSeries *series = new QLineSeries();
        *series << QPointF(0, 6) << QPointF(9, 4) << QPointF(15, 30) << QPointF(25, 13) << QPointF(29, 26);
        QChart *chart = new QChart();
        chart->legend()->hide();
        chart->addSeries(series);

}


mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QHBoxLayout" name="horizontalLayout_2">
    <item>
     <widget class="QFrame" name="frame">
      <property name="frameShape">
       <enum>QFrame::StyledPanel</enum>
      </property>
      <property name="frameShadow">
       <enum>QFrame::Raised</enum>
      </property>
      <layout class="QHBoxLayout" name="horizontalLayout">
       <item>
        <widget class="QFrame" name="frame_2">
         <property name="frameShape">
          <enum>QFrame::StyledPanel</enum>
         </property>
         <property name="frameShadow">
          <enum>QFrame::Raised</enum>
         </property>
         <layout class="QVBoxLayout" name="verticalLayout">
          <item>
           <widget class="QFrame" name="lcdframe">
            <property name="maximumSize">
             <size>
              <width>200</width>
              <height>50</height>
             </size>
            </property>
            <property name="frameShape">
             <enum>QFrame::StyledPanel</enum>
            </property>
            <property name="frameShadow">
             <enum>QFrame::Raised</enum>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QFrame" name="chartframe">
            <property name="minimumSize">
             <size>
              <width>200</width>
              <height>100</height>
             </size>
            </property>
            <property name="frameShape">
             <enum>QFrame::StyledPanel</enum>
            </property>
            <property name="frameShadow">
             <enum>QFrame::Raised</enum>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QPushButton" name="pushButton">
            <property name="text">
             <string>PushButton</string>
            </property>
           </widget>
          </item>
         </layout>
        </widget>
       </item>
       <item>
        <widget class="QFrame" name="frame_3">
         <property name="frameShape">
          <enum>QFrame::StyledPanel</enum>
         </property>
         <property name="frameShadow">
          <enum>QFrame::Raised</enum>
         </property>
         <layout class="QVBoxLayout" name="verticalLayout_2">
          <item>
           <widget class="QTextEdit" name="textEdit"/>
          </item>
          <item>
           <widget class="QLineEdit" name="lineEdit"/>
          </item>
         </layout>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <widget class="QToolBar" name="toolBar">
   <property name="windowTitle">
    <string>toolBar</string>
   </property>
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

I am a beginner in the qt framework and I am super short of time. I tried many solutions but couldn't reach a proper one. I will be waiting for your kind response.


Solution

  • you need to do like this:

    1. QLineSeries and QChart move to main mainwindow.h

      private: 
      QLineSeries *series;
      QChart *chart; 
      

    2.in mainwindow.cpp it will already be like this

    ui->setupUi(this);
        //![1]
            series = new QLineSeries();
            *series << QPointF(0, 6) << QPointF(9, 4) << QPointF(15, 20) << QPointF(25, 12) << QPointF(29, 26);
            chart = new QChart();
            chart->legend()->hide();
            chart->addSeries(series);
        //![1]
    
    1. in function on_pushButton_clicked()

       series ->clear();
       series ->append(QPointF(0, 6));
       series ->append(QPointF(9, 4));
      

      // or

    *series << QPointF(0, 6) << QPointF(9, 4) << QPointF(15, 30) << QPointF(25, 13) << QPointF(29, 26);

    no need to create new QLineSeries and QChart in on_pushButton_clicked function