Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Deleting QChart Causes 30+ Second Application Hang!
Forum Updated to NodeBB v4.3 + New Features

Deleting QChart Causes 30+ Second Application Hang!

Scheduled Pinned Locked Moved Unsolved General and Desktop
51 Posts 5 Posters 3.9k Views 2 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.
  • J JoeCFD
    5 Mar 2025, 18:47

    @FleetingMemory I tried Jon's code with 10000 series + 10 points and tried different things:

    1. disable update of QChartView
    2. disable QChartView and QChart
    3. hide QChartView and QChart
      before chart is deleted. Nothing helps.

    However, I am able to get quick clean-up of qchartview with

        chartView->setChart( new QChart() );
        chart->deleteLater();
    

    Not sure if this helps you. If this piece of code does not help, you may try to delete the chart in a thread while charview is available for other uses. I guess your app will have issue at exit.

    F Offline
    F Offline
    FleetingMemory
    wrote on 5 Mar 2025, 19:41 last edited by
    #31
    This post is deleted!
    1 Reply Last reply
    0
    • J JoeCFD
      5 Mar 2025, 18:47

      @FleetingMemory I tried Jon's code with 10000 series + 10 points and tried different things:

      1. disable update of QChartView
      2. disable QChartView and QChart
      3. hide QChartView and QChart
        before chart is deleted. Nothing helps.

      However, I am able to get quick clean-up of qchartview with

          chartView->setChart( new QChart() );
          chart->deleteLater();
      

      Not sure if this helps you. If this piece of code does not help, you may try to delete the chart in a thread while charview is available for other uses. I guess your app will have issue at exit.

      F Offline
      F Offline
      FleetingMemory
      wrote on 5 Mar 2025, 19:44 last edited by FleetingMemory 3 May 2025, 19:45
      #32

      @JoeCFD I tried that as well, it is marginally faster to delete this way than removeAll. I have tried threading but because QChart calls GUI functions, I was not able to get it to work. I tried threading the delete as well as the removal of Series. Neither works. I usually run into errors like -- widget cannot be moved to a new thread -- accessing widget from wrong thread (usually pertains to the QChartData) -- sending signal accross thread, which results in an immediate crash. This is because the removeALLSeries and delete call on update()

      J 1 Reply Last reply 5 Mar 2025, 20:20
      0
      • S Offline
        S Offline
        SGaist
        Lifetime Qt Champion
        wrote on 5 Mar 2025, 19:49 last edited by
        #33

        Hi,

        Did you try calling setUpdateEnabled(false) on the chart ?

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        F 1 Reply Last reply 5 Mar 2025, 20:05
        0
        • S SGaist
          5 Mar 2025, 19:49

          Hi,

          Did you try calling setUpdateEnabled(false) on the chart ?

          F Offline
          F Offline
          FleetingMemory
          wrote on 5 Mar 2025, 20:05 last edited by FleetingMemory 3 May 2025, 20:06
          #34

          @SGaist QChart does not have updatesEnabled(false) only QChartView. Doesn't seem to make a difference. I also tried blocking signals.

          1 Reply Last reply
          0
          • F FleetingMemory
            5 Mar 2025, 19:44

            @JoeCFD I tried that as well, it is marginally faster to delete this way than removeAll. I have tried threading but because QChart calls GUI functions, I was not able to get it to work. I tried threading the delete as well as the removal of Series. Neither works. I usually run into errors like -- widget cannot be moved to a new thread -- accessing widget from wrong thread (usually pertains to the QChartData) -- sending signal accross thread, which results in an immediate crash. This is because the removeALLSeries and delete call on update()

            J Offline
            J Offline
            JoeCFD
            wrote on 5 Mar 2025, 20:20 last edited by
            #35

            @FleetingMemory My results with Jon's code:

            1. use deleteLater
              Starting to delete
              Finished deleting 771
            2. original deletion
              Starting to delete
              Finished deleting 11663

            Qt 6.8.2 + Ubuntu 22.04

            F 1 Reply Last reply 5 Mar 2025, 20:23
            0
            • J JoeCFD
              5 Mar 2025, 20:20

              @FleetingMemory My results with Jon's code:

              1. use deleteLater
                Starting to delete
                Finished deleting 771
              2. original deletion
                Starting to delete
                Finished deleting 11663

              Qt 6.8.2 + Ubuntu 22.04

              F Offline
              F Offline
              FleetingMemory
              wrote on 5 Mar 2025, 20:23 last edited by FleetingMemory 3 May 2025, 20:25
              #36

              @JoeCFD how many series? It still locks the main thread though... I did not see a noticeable difference between delete and deleteLater performance on my side

              J 1 Reply Last reply 5 Mar 2025, 20:30
              0
              • F FleetingMemory
                5 Mar 2025, 20:23

                @JoeCFD how many series? It still locks the main thread though... I did not see a noticeable difference between delete and deleteLater performance on my side

                J Offline
                J Offline
                JoeCFD
                wrote on 5 Mar 2025, 20:30 last edited by JoeCFD 3 May 2025, 20:35
                #37

                @FleetingMemory 10000 series + 10 points

                Jon's code and chartView is not deleted. Series are cleared quickly.

                #include "chart.h"
                
                // using namespace QtCharts;
                
                Widget::Widget(QWidget *parent)
                    : QWidget(parent)
                {
                    setGeometry(100, 100, 800, 600);
                    setLayout(new QVBoxLayout);
                
                    this->chart = new QChart();
                    this->chartView = new QChartView(chart, this);
                    layout()->addWidget(chartView);
                    chartView->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
                
                    for (int i = 0; i < 10000; i++)
                    {
                        QLineSeries* series = new QLineSeries();
                        for (int x = 0; x < 10; x++)
                            series->append(x, x * (i + 1));
                        chart->addSeries(series);
                    }
                    
                    chart->createDefaultAxes();
                    chart->axes(Qt::Horizontal).first()->setTitleText("X Axis");
                    chart->axes(Qt::Vertical).first()->setTitleText("Y Axis");
                    QTimer::singleShot(5000, this, &Widget::deleteChart);
                }
                
                void Widget::deleteChart()
                {
                    QElapsedTimer elapsed;
                    qDebug() << "Starting to delete";
                    elapsed.start(); 
                
                    chartView->setChart( new QChart() );
                    chart->deleteLater();
                
                    layout()->removeWidget(chartView);
                    //chart->removeAllSeries();
                    //delete chart;
                    //chart = nullptr;
                    //delete chartView;
                    //chartView = nullptr;
                    qDebug() << "Finished deleting" << elapsed.elapsed();
                }
                
                Widget::~Widget() {}
                
                F 1 Reply Last reply 5 Mar 2025, 21:03
                0
                • J JoeCFD
                  5 Mar 2025, 20:30

                  @FleetingMemory 10000 series + 10 points

                  Jon's code and chartView is not deleted. Series are cleared quickly.

                  #include "chart.h"
                  
                  // using namespace QtCharts;
                  
                  Widget::Widget(QWidget *parent)
                      : QWidget(parent)
                  {
                      setGeometry(100, 100, 800, 600);
                      setLayout(new QVBoxLayout);
                  
                      this->chart = new QChart();
                      this->chartView = new QChartView(chart, this);
                      layout()->addWidget(chartView);
                      chartView->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
                  
                      for (int i = 0; i < 10000; i++)
                      {
                          QLineSeries* series = new QLineSeries();
                          for (int x = 0; x < 10; x++)
                              series->append(x, x * (i + 1));
                          chart->addSeries(series);
                      }
                      
                      chart->createDefaultAxes();
                      chart->axes(Qt::Horizontal).first()->setTitleText("X Axis");
                      chart->axes(Qt::Vertical).first()->setTitleText("Y Axis");
                      QTimer::singleShot(5000, this, &Widget::deleteChart);
                  }
                  
                  void Widget::deleteChart()
                  {
                      QElapsedTimer elapsed;
                      qDebug() << "Starting to delete";
                      elapsed.start(); 
                  
                      chartView->setChart( new QChart() );
                      chart->deleteLater();
                  
                      layout()->removeWidget(chartView);
                      //chart->removeAllSeries();
                      //delete chart;
                      //chart = nullptr;
                      //delete chartView;
                      //chartView = nullptr;
                      qDebug() << "Finished deleting" << elapsed.elapsed();
                  }
                  
                  Widget::~Widget() {}
                  
                  F Offline
                  F Offline
                  FleetingMemory
                  wrote on 5 Mar 2025, 21:03 last edited by
                  #38

                  @JoeCFD Going back to my original code, I tried moving setchart(new QChart()) and deletelater() to before I populate the new chart with new series. Previously I was populating a new chart then setting it, then deleting a pointer to the old chart. Now, if I watch the memory, deleteLater still doesn't actually call delete until after the new chart is populated fully. So it looks like it deleted quickly but it still hangs after the new chart pops in with data. Doing it this way, however does take slightly less time to delete.

                  J 1 Reply Last reply 6 Mar 2025, 12:08
                  0
                  • F FleetingMemory
                    5 Mar 2025, 21:03

                    @JoeCFD Going back to my original code, I tried moving setchart(new QChart()) and deletelater() to before I populate the new chart with new series. Previously I was populating a new chart then setting it, then deleting a pointer to the old chart. Now, if I watch the memory, deleteLater still doesn't actually call delete until after the new chart is populated fully. So it looks like it deleted quickly but it still hangs after the new chart pops in with data. Doing it this way, however does take slightly less time to delete.

                    J Offline
                    J Offline
                    JoeCFD
                    wrote on 6 Mar 2025, 12:08 last edited by JoeCFD 6 days ago
                    #39

                    @FleetingMemory Maybe try to delete it in a thread. Also a splash widget may be needed at exit.

                    F 1 Reply Last reply 6 Mar 2025, 21:24
                    0
                    • J JoeCFD
                      6 Mar 2025, 12:08

                      @FleetingMemory Maybe try to delete it in a thread. Also a splash widget may be needed at exit.

                      F Offline
                      F Offline
                      FleetingMemory
                      wrote on 6 Mar 2025, 21:24 last edited by FleetingMemory 6 days ago
                      #40

                      @JoeCFD Can't delete in a thread, it calls on GUI functions because it loops across removeSeries(), which calls update. This causes a cross-thread exception in Qt. DeleteLater() doesn't actually delete immediately within your timer bounds in the code you posted above (that is just timing QT scheduling it), so it still freezes the program later on.

                      1 Reply Last reply
                      0
                      • J Online
                        J Online
                        JonB
                        wrote on 7 Mar 2025, 13:42 last edited by JonB 24 days from now
                        #41

                        @FleetingMemory
                        As you have now discovered, it is the deleting of each series which is so time consuming (for unknown reasons). There is a huge difference between 10 series with 10,000 points each versus 10,000 series with 10 points each. (In fact, in latter case timing is same even if all series are empty/have no points.) There seems to be little you can do to affect that timing. I see no evidence it has anything to do with whether the view/chart/series are shown or not, have signals disabled or not, etc.

                        Which takes me back to my question as to why you need 10,000 series or any such figure, which you did not answer. There is no chance the user can view or appreciate such a large number, so what is the point of adding that many onto the chart in the first place? That is where I would look for efficiency improvement.

                        If you really are not prepared to reduce that, then: I presume any deleteLater() won't help as that just delays when the delay comes to a bit later. I assume you are right that series cannot or should not be deleted from a thread as they are some kind of UI object. Which would leave you with one possible "hack" to distribute the deletion time "nicely". Follow @JoeCFD's code to assign a new, blank chart to the view (chartView->setChart( new QChart() );). But do not immediately delete the original chart there: instead, keep it around in a suitable variable. In UI code thread set off a repeating timer every so often: in each timeout use removeSeries() to delete a few of the 10,000 series, example perhaps 100 at a time. You can do this because you are in the main/UI thread. Over time you will have deleted all the series from the old QChart object, at that point you can delete the (empty) chart and terminate the timer. Seems to me reducing the number of series in the first place is preferable, but there you are if you really want to do this.

                        F 1 Reply Last reply 7 Mar 2025, 16:45
                        1
                        • J JonB
                          7 Mar 2025, 13:42

                          @FleetingMemory
                          As you have now discovered, it is the deleting of each series which is so time consuming (for unknown reasons). There is a huge difference between 10 series with 10,000 points each versus 10,000 series with 10 points each. (In fact, in latter case timing is same even if all series are empty/have no points.) There seems to be little you can do to affect that timing. I see no evidence it has anything to do with whether the view/chart/series are shown or not, have signals disabled or not, etc.

                          Which takes me back to my question as to why you need 10,000 series or any such figure, which you did not answer. There is no chance the user can view or appreciate such a large number, so what is the point of adding that many onto the chart in the first place? That is where I would look for efficiency improvement.

                          If you really are not prepared to reduce that, then: I presume any deleteLater() won't help as that just delays when the delay comes to a bit later. I assume you are right that series cannot or should not be deleted from a thread as they are some kind of UI object. Which would leave you with one possible "hack" to distribute the deletion time "nicely". Follow @JoeCFD's code to assign a new, blank chart to the view (chartView->setChart( new QChart() );). But do not immediately delete the original chart there: instead, keep it around in a suitable variable. In UI code thread set off a repeating timer every so often: in each timeout use removeSeries() to delete a few of the 10,000 series, example perhaps 100 at a time. You can do this because you are in the main/UI thread. Over time you will have deleted all the series from the old QChart object, at that point you can delete the (empty) chart and terminate the timer. Seems to me reducing the number of series in the first place is preferable, but there you are if you really want to do this.

                          F Offline
                          F Offline
                          FleetingMemory
                          wrote on 7 Mar 2025, 16:45 last edited by
                          #42

                          @JonB said in Deleting QChart Causes 30+ Second Application Hang!:

                          Which takes me back to my question as to why you need 10,000 series or any such figure, which you did not answer. There is no chance the user can view or appreciate such a large number, so what is the point of adding that many onto the chart in the first place? That is where I would look for efficiency improvement.

                          The chart is to be used for displaying & isolating specific data/time frames, thus all data/lines need to be present, and each series is a line being displayed. By manipulating the X-Axis the user can zoom into/out of to a specific time frame. The idea of deleting a few at a time is something I have definitely been exploring as a possible solution however it doesn't fix the fact it will still hang the whole application when the window is closed or application exited as well.

                          J 1 Reply Last reply 7 Mar 2025, 17:12
                          0
                          • F FleetingMemory
                            7 Mar 2025, 16:45

                            @JonB said in Deleting QChart Causes 30+ Second Application Hang!:

                            Which takes me back to my question as to why you need 10,000 series or any such figure, which you did not answer. There is no chance the user can view or appreciate such a large number, so what is the point of adding that many onto the chart in the first place? That is where I would look for efficiency improvement.

                            The chart is to be used for displaying & isolating specific data/time frames, thus all data/lines need to be present, and each series is a line being displayed. By manipulating the X-Axis the user can zoom into/out of to a specific time frame. The idea of deleting a few at a time is something I have definitely been exploring as a possible solution however it doesn't fix the fact it will still hang the whole application when the window is closed or application exited as well.

                            J Offline
                            J Offline
                            JoeCFD
                            wrote on 7 Mar 2025, 17:12 last edited by JoeCFD 24 days from now
                            #43

                            @FleetingMemory that is why I wrote earlier that you need a splash widget with some nice animation at exit and make your app wait for these series to be cleared.

                            You can also file a bug with Jon's test code to Qt for optimization in removeAllSeries call. I guess one update may be enough instead of one update after one deletion.

                            F 2 Replies Last reply 7 Mar 2025, 17:51
                            0
                            • C Online
                              C Online
                              Christian Ehrlicher
                              Lifetime Qt Champion
                              wrote on 7 Mar 2025, 17:24 last edited by
                              #44

                              I've tested @JonB 's code with 12000 series / 40 data points each in debug mode:

                              Starting to create
                              Finished creating 32858
                              Starting to delete
                              Finished deleting 195421

                              Digged a little bit around to see what happens during destruction. The most time the legend gets updated... so:
                              I added this before delete chart;:
                              delete chart->legend();

                              -->
                              Starting to create
                              Finished creating 33861
                              Starting to delete
                              Finished deleting 27167

                              The best thing I found is to add d_ptr->m_dataset->disconnect(); in QChart dtor. I doubt this will go in into official QtCharts since it's in maintainance mode only.

                              -->
                              Starting to create
                              Finished creating 31901
                              Starting to delete
                              Finished deleting 16988

                              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                              Visit the Qt Academy at https://academy.qt.io/catalog

                              J F 2 Replies Last reply 7 Mar 2025, 17:46
                              1
                              • C Christian Ehrlicher
                                7 Mar 2025, 17:24

                                I've tested @JonB 's code with 12000 series / 40 data points each in debug mode:

                                Starting to create
                                Finished creating 32858
                                Starting to delete
                                Finished deleting 195421

                                Digged a little bit around to see what happens during destruction. The most time the legend gets updated... so:
                                I added this before delete chart;:
                                delete chart->legend();

                                -->
                                Starting to create
                                Finished creating 33861
                                Starting to delete
                                Finished deleting 27167

                                The best thing I found is to add d_ptr->m_dataset->disconnect(); in QChart dtor. I doubt this will go in into official QtCharts since it's in maintainance mode only.

                                -->
                                Starting to create
                                Finished creating 31901
                                Starting to delete
                                Finished deleting 16988

                                J Online
                                J Online
                                JonB
                                wrote on 7 Mar 2025, 17:46 last edited by JonB 24 days from now
                                #45

                                @Christian-Ehrlicher
                                All I saw was all the time being spent in removeAllSeries(), or whichever you remove series if one by one. I looked at remoceSeries() source code online but I don't have sources to dig further. I don't know how that is affected by legend. Nothing struck me except however it is storing its model data. That could relate to your d_ptr->m_dataset. And d_ptr requires OP to change and compile Qt sources, right?

                                It's taking 30 seconds to get rid of 10,000 series which it never took 30 seconds to create, it is a lot of time per series.

                                P.S.
                                Of course, as you say QtCharts is going so realise nothing is going to be done about sources.

                                1 Reply Last reply
                                0
                                • C Christian Ehrlicher
                                  7 Mar 2025, 17:24

                                  I've tested @JonB 's code with 12000 series / 40 data points each in debug mode:

                                  Starting to create
                                  Finished creating 32858
                                  Starting to delete
                                  Finished deleting 195421

                                  Digged a little bit around to see what happens during destruction. The most time the legend gets updated... so:
                                  I added this before delete chart;:
                                  delete chart->legend();

                                  -->
                                  Starting to create
                                  Finished creating 33861
                                  Starting to delete
                                  Finished deleting 27167

                                  The best thing I found is to add d_ptr->m_dataset->disconnect(); in QChart dtor. I doubt this will go in into official QtCharts since it's in maintainance mode only.

                                  -->
                                  Starting to create
                                  Finished creating 31901
                                  Starting to delete
                                  Finished deleting 16988

                                  F Offline
                                  F Offline
                                  FleetingMemory
                                  wrote on 7 Mar 2025, 17:50 last edited by
                                  #46

                                  @Christian-Ehrlicher I currently have legend disabled, is it still updating in the background even with it off?

                                  1 Reply Last reply
                                  0
                                  • J JoeCFD
                                    7 Mar 2025, 17:12

                                    @FleetingMemory that is why I wrote earlier that you need a splash widget with some nice animation at exit and make your app wait for these series to be cleared.

                                    You can also file a bug with Jon's test code to Qt for optimization in removeAllSeries call. I guess one update may be enough instead of one update after one deletion.

                                    F Offline
                                    F Offline
                                    FleetingMemory
                                    wrote on 7 Mar 2025, 17:51 last edited by FleetingMemory 24 days from now
                                    #47

                                    original bug report was ignored, had to refile and explain more. Linked the new report below

                                    1 Reply Last reply
                                    0
                                    • J JoeCFD
                                      7 Mar 2025, 17:12

                                      @FleetingMemory that is why I wrote earlier that you need a splash widget with some nice animation at exit and make your app wait for these series to be cleared.

                                      You can also file a bug with Jon's test code to Qt for optimization in removeAllSeries call. I guess one update may be enough instead of one update after one deletion.

                                      F Offline
                                      F Offline
                                      FleetingMemory
                                      wrote on 7 Mar 2025, 17:53 last edited by
                                      #48

                                      @JoeCFD Filed the bug report yesterday -- Feel free to add any findings to it!
                                      https://bugreports.qt.io/browse/QTBUG-134490

                                      J 1 Reply Last reply 7 Mar 2025, 19:10
                                      0
                                      • C Online
                                        C Online
                                        Christian Ehrlicher
                                        Lifetime Qt Champion
                                        wrote on 7 Mar 2025, 17:55 last edited by
                                        #49

                                        As I already said QtCharts is deprecated. Nothing will be changed there. I gave you two solutions...

                                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                        Visit the Qt Academy at https://academy.qt.io/catalog

                                        1 Reply Last reply
                                        2
                                        • F FleetingMemory
                                          7 Mar 2025, 17:53

                                          @JoeCFD Filed the bug report yesterday -- Feel free to add any findings to it!
                                          https://bugreports.qt.io/browse/QTBUG-134490

                                          J Offline
                                          J Offline
                                          JoeCFD
                                          wrote on 7 Mar 2025, 19:10 last edited by
                                          #50

                                          @FleetingMemory They will not fix it for you. Maybe you can dig into the source code of this module and try some fixes. Then build it for yourself.

                                          1 Reply Last reply
                                          1

                                          40/51

                                          6 Mar 2025, 21:24

                                          • Login

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