Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Problem with data visualization in QCharts and multithreading



  • Hello everyone.
    I got a problem regarding QChartView and widgets in general when used with multithreading.

    I got a code like this

    QChart         *chart_plot;
    QChartView     *chartView_plot;
    QLineSeries    *series_plot;
    

    in my mainwindow.h and like this

    series_plot = new QLineSeries();
    chart_plot = new QChart();
    chart_plot->addSeries(series_plot);
    
    // etc...
    
    chartView_plot = new QChartView;
    chartView_plot->setChart(chart_plot);
    chartView_plot->setRenderHint(QPainter::Antialiasing,true);
    
    ui->gridLayout_plots->addWidget(chartView_plot,1,0,1,3);
    

    in my mainwindow.cpp ant it works fine with the following result:

    img1.png

    However, since there are more charts in my GUI and everything starts beeing slower and less reactive, I was thinking about letting another thread to manage the data visualization.
    Then i created another object "MyThread_navigation" with

    QChart         *chart_plot;
    QChartView     *chartView_plot;
    QLineSeries    *series_plot;
    

    in mythread_navigation.h and

    void MyThread_navigation::setup_thread(QThread &cThread, QChartView *chartview)
    {
    series_plot = new QLineSeries();
    chart_plot = new QChart();
    chart_plot->addSeries(series_plot);
    
    // etc...
    
    chartView_plot = new QChartView(chartview);
    chartView_plot->setChart(chart_plot);
    chartView_plot->setRenderHint(QPainter::Antialiasing,true);
    
    connect(&cThread,SIGNAL(started()),this,SLOT(start_thread()));
    }
    

    in mythread_navigation.cpp.
    Then, I wrote

    MyThread_navigation *worker_navigation;           // Worker for navigation data visualization
    QThread             *thread_navigation;           // Thread for navigation data visualization
    

    in mainwindow.h and this

    chartView_plot = new QChartView();
    chartView_plot->setRenderHint(QPainter::Antialiasing,true);
    
    ui->gridLayout_plots->addWidget(chartView_plot,1,0,1,3);
    
    thread_navigation = new QThread();
    worker_navigation = new MyThread_navigation();
    
    worker_navigation->setup_thread(*thread_navigation,chartView_plot);
    worker_navigation->moveToThread(thread_navigation);
    
    connect(this, SIGNAL(quit_threads()), thread_navigation, SLOT(quit()));
    connect(this, SIGNAL(quit_threads()), worker_navigation, SLOT(deleteLater()));
    connect(thread_navigation, SIGNAL(finished()), thread_navigation, SLOT(deleteLater()));
    
    thread_navigation->start();
    

    in mainwindow.cpp.

    The result is the following:
    img2.png

    Moreover, when I resize the GUI window, that small chart does not appear to change its size.
    It seems that when I pass a widget to another class and move that class to my QThread object, my chart won't resize to the layout's size in which it is contained.

    In previous codes I wrote something like

    graph_surface = new Q3DSurface();
    container     = QWidget::createWindowContainer(graph_surface);
    
    ui->gridLayout_visual->addWidget(container,1,0,6,1);
    graph_surface->setHorizontalAspectRatio(container->width()/container->height());
    graph_surface->setHeight(container->height());
    
    container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    container->setFocusPolicy(Qt::StrongFocus);
    
    // etc.
    
    thread_visual = new QThread;
    worker_visual = new MyThread_visualization();
    
    worker_visual->setup_thread(*thread_visual, graph_surface);
    worker_visual->moveToThread(thread_visual_RA);
    thread_visual->start();
    

    and It used to work fine. The problem is that createWindowContainer doesn't take a QChartView as a input (only QWindow apparently).
    How can I solve this?
    How can I "put" a QChartView (QWidget) in a container (if it solves my problem)?
    Is there a better way to make another thread to manage data visualization on a chart?

    Thank you in advance of any reply :-)
    Bye bye


  • Lifetime Qt Champion

    You must not modify any gui elements outside the main gui thread. You can move the calculation into a separate thread and then send the result via signals and slots to the main gui thread.



  • Thank you for your advice. I did as you said and it seems it's working well.