Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Solved How to free RAM after using QChartView?

    General and Desktop
    2
    10
    473
    Loading More Posts
    • 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.
    • H
      HTWAMD last edited by

      Hey,

      I'm using a simple code to draw a chart, here an example - just the values of the QLineSeries are faked:

      QLineSeries *series = new QLineSeries();
      
      series->append(0, 1);
      series->append(1, 2);
      series->append(2, 5);
      series->append(3, 3);
      
      QChart *chart = new QChart();
      chart->legend()->hide();
      chart->addSeries(series);
      chart->createDefaultAxes();
      
      QChartView *chartView = new QChartView(chart);
      chartView->setRenderHint(QPainter::Antialiasing);
      chartView->resize(800, 600);
      chartView->show();
      

      I now have the problem that I use more RAM with every call. What's the correct way to handle it?
      I tried to save the pointer of the Chart, ChartView and LineSeries and constantly checking if the window is still open/active. If the window is closed, I tried to use the deleteLater function but this crashs my application.

      Can someone help please? Thanks

      1 Reply Last reply Reply Quote 0
      • Christian Ehrlicher
        Christian Ehrlicher Lifetime Qt Champion last edited by

        @HTWAMD said in How to free RAM after using QChartView?:

        What's the correct way to handle it?

        You're creating objects without deleting them - so delete them and the memory will be freed - C++ basics.

        Qt has to stay free or it will die.

        1 Reply Last reply Reply Quote 1
        • H
          HTWAMD last edited by

          Well yes, sure. But like I said using the delete or deleteLater function isn't working. It crashes the whole application.

          chartView->deleteLater();
          chart->deleteLater();
          //Or
          delete chartView;
          delete chart; 
          
          

          I tried these function after the window of the chart is closed but no success.

          1 Reply Last reply Reply Quote 0
          • Christian Ehrlicher
            Christian Ehrlicher Lifetime Qt Champion last edited by Christian Ehrlicher

            @HTWAMD said in How to free RAM after using QChartView?:

            It crashes the whole application.

            Because you delete it twice:

            https://doc.qt.io/qt-5/qchartview.html#QChartView-1 : The ownership of the chart is passed to the chart view.

            And please provide a minimal example where it crashes - you code above doesn't show where/how you delete the objects.

            Qt has to stay free or it will die.

            1 Reply Last reply Reply Quote 2
            • H
              HTWAMD last edited by

              I tried some more stuff but I' cant deal with the Chart stuff :(

              Here is - basically - my code I use (header + source, the ui contains just a widget and two spinboxes):

              namespace Ui {
              class EventDrawer;
              }
              
              class EventDrawer : public QWidget
              {
                  Q_OBJECT
              
              public:
                  explicit EventDrawer(QWidget *parent, QTableWidget* listEvents);
                  ~EventDrawer();
                  void draw_chart();
              
              public slots:
                  void closeEvent (QCloseEvent *event);
              
              private slots:
                  void on_spinBox_min_valueChanged(int arg1);
                  void on_spinBox_max_valueChanged(int arg1);
              
              private:
                  Ui::EventDrawer *ui;
              
                  QChart* Chart;
                  QChartView* chartView;
                  QVBoxLayout* LayoutChart;
                  QLineSeries* series;
                  QTableWidget* table_ptr;
              
                  bool init;
                  int min_value;
                  int max_value;
              };
              
              #endif // EVENTDRAWER_H
              
              
              
              
              #include "eventdrawer.h"
              #include "ui_eventdrawer.h"
              
              EventDrawer::EventDrawer(QWidget *parent, QTableWidget* listEvents) :
                  ui(new Ui::EventDrawer)
              {
                  ui->setupUi(this);
                  this->setStyleSheet(parent->styleSheet());
              
                  init = true;
                  min_value = 0;
                  max_value = 0;
              
                  table_ptr = listEvents;
                  draw_chart();
                  init = false;
              }
              
              EventDrawer::~EventDrawer()
              {
                  delete ui;
              }
              
              void EventDrawer::closeEvent (QCloseEvent *event)
              {
                  delete ui->widget->layout();
              
                  event->accept();
              }
              
              void EventDrawer::draw_chart()
              {
                  int counter = 1;
                  QMap<QString, int> InfoTypes;
                  for (int i=0; i < table_ptr->rowCount(); i++)
                  {
                      int value = i;
                      QString info_type = table_ptr->item(value, 1)->text();
                      if (InfoTypes[info_type] == 0)
                          InfoTypes[info_type] = counter++;
                  }
              
                  int event_type_count = InfoTypes.count();
                  if (event_type_count == 0)
                      return;
              
              
                  int min = 9999999;
                  int max = -9999999;
              
                  series = new QLineSeries[event_type_count];
                  for (int i=0; i < table_ptr->rowCount(); i++)
                  {
                      int value = i;
                      if (ui->checkBox_oldFirst->isChecked())
                          value = (table_ptr->rowCount()-1) - i;
              
                      QString info_type = table_ptr->item(value, 1)->text();
                      float info_value = table_ptr->item(value, 2)->text().toFloat();
              
                      if (info_value < min)
                          min = info_value;
                      if (info_value > max)
                          max = info_value;
              
                      if (ui->checkBox_dateAxis->isChecked())
                      {
                          QDateTime timestamp = QDateTime::fromString(table_ptr->item(value, 3)->text(), "yyyy-MM-dd hh:mm:ss.zzz");
                          series[InfoTypes[info_type]-1].append(timestamp.toMSecsSinceEpoch(), info_value);
                      }
                      else
                      {
                          series[InfoTypes[info_type]-1].append(i, info_value);
                      }
                      series[InfoTypes[info_type]-1].setName(info_type);
                  }
              
                  Chart = new QChart();
                  for (int i=0; i < event_type_count; i++)
                      Chart->addSeries(&series[i]);
              
                  if (ui->checkBox_dateAxis->isChecked())
                  {
                      QDateTimeAxis *axisX = new QDateTimeAxis;
                      axisX->setTickCount(14);
                      axisX->setFormat("MM.dd hh:mm:ss");
                      axisX->setTitleText("Date");
                      Chart->addAxis(axisX, Qt::AlignBottom);
                      series->attachAxis(axisX);
                      Chart->axisX()->setTitleText("Date");
              
                      QValueAxis *axisY = new QValueAxis;
                      axisY->setLabelFormat("%i");
                      Chart->addAxis(axisY, Qt::AlignLeft);
                      series->attachAxis(axisY);
                  }
                  else
                  {
                      Chart->createDefaultAxes();
                      Chart->axisX()->setRange(0, table_ptr->rowCount());
                  }
              
                  if (min_value != 0 || max_value != 0)
                  {
                      Chart->axisY()->setRange(min_value, max_value);
                  }
                  else
                  {
                      ui->spinBox_max->setValue(max);
                      ui->spinBox_min->setValue(min);
                  }
              
                  chartView = new QChartView(Chart);
                  chartView->setRenderHint(QPainter::Antialiasing);
              
                  LayoutChart = new QVBoxLayout();
                  LayoutChart->addWidget(chartView);
                  ui->widget->setLayout(LayoutChart);
              }
              
              void EventDrawer::on_spinBox_min_valueChanged(int arg1)
              {
                  if (init)
                      return;
              
                  min_value = arg1;
                  Chart->axisY()->setRange(min_value, max_value);
              }
              
              void EventDrawer::on_spinBox_max_valueChanged(int arg1)
              {
                  if (init)
                      return;
              
                  max_value = arg1;
                  Chart->axisY()->setRange(min_value, max_value);
              }
              

              What I would like to do now, is to delete / free the ram when the window is closed. So if the closeEvent function is called, delete the chartView, Chart, Series.
              Could someone please show me how to do this?

              1 Reply Last reply Reply Quote 0
              • Christian Ehrlicher
                Christian Ehrlicher Lifetime Qt Champion last edited by

                Again: please provide a minimal, compilable example if you think there is a crash and / or a memleak. Delete your chartView in the dtor and the memory will be freed afaics.

                Qt has to stay free or it will die.

                1 Reply Last reply Reply Quote 0
                • H
                  HTWAMD last edited by

                  Okay I made a very short, compilable example, here is the download link:
                  https://filetransfer.io/data-package/wck4NloP

                  Compile, run the application, click draw chart, close the window, crash.
                  Can you or anyone please tell me how to modify the code / the dtor to avoid the crash?

                  1 Reply Last reply Reply Quote 0
                  • Christian Ehrlicher
                    Christian Ehrlicher Lifetime Qt Champion last edited by

                    First in the dtor only 'delete ui' is needed - the rest is deleted due to parent child relationships.

                    Second please take a look at

                    QLineSeries *series = new QLineSeries[event_type_count];
                    ...
                    Chart->addSeries(&series[i]);
                    

                    since addSeries() is taking ownership, it's later also calling 'delete &series[i]' - this can't work.

                    Use a QVector<QLineSeries*>, no need to hold it as member (at least not in your testcase).

                    Qt has to stay free or it will die.

                    1 Reply Last reply Reply Quote 1
                    • H
                      HTWAMD last edited by HTWAMD

                      Thanks a lot.
                      dtor is now delete ui only and the QLineSeries using a QVector, now it's working perfectly :)

                      Christian Ehrlicher 1 Reply Last reply Reply Quote 0
                      • Christian Ehrlicher
                        Christian Ehrlicher Lifetime Qt Champion @HTWAMD last edited by

                        @HTWAMD Then please mark this topic as solved, thx.

                        Qt has to stay free or it will die.

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post