It is safe to call QCustomPlot::replot()
with QCustomPlot::rpRefreshHint
in another thread? I know that is not a good idea to manipulate QWidget
from other threads, But my problem was plotting 6k(1k per graph) points in 5 instance of QCustomPlot
(points are added using QCPGraph::addData()
and I got performance issues with QCustomPlot::replot()
.
So I tried to move QCustomPlot::replot
to another thread and it just work fine without any issue and the performance problem was fixed.
Sample Code:
#include "qcustomplot.h" #include <QApplication> #include <QPointer> #include <QVector> #include <QThread> #include <QTimer> #include <QTime> class QCustomPlotUpdater : public QObject { public: QCustomPlotUpdater(QVector<QPointer<QCustomPlot>> const& plots) : plots_(plots), thread_(new QThread), start_time_(QTime::currentTime()) { connect(thread_, &QThread::finished, this, &QObject::deleteLater); connect(thread_, &QThread::started, &updater_, qOverload<>(&QTimer::start)); connect(&updater_, &QTimer::timeout, this, &QCustomPlotUpdater::addNewPoint); updater_.setInterval(std::chrono::milliseconds(16)); } void start() { thread_->start(); } private: void addNewPoint() { double const key = start_time_.msecsTo(QTime::currentTime()) / 1000.0; for (auto const& plot : plots_) { for (int index = 0, end = plot->graphCount(); index < end; ++index) { plot->graph(index)->addData( key * ((index + 1) * 0.25), qSin(key) + std::rand() / (double)RAND_MAX * 1 * qSin(key / 0.3843)); } plot->rescaleAxes(); plot->replot(QCustomPlot::rpRefreshHint); } } QVector<QPointer<QCustomPlot>> plots_; QPointer<QThread> thread_; QTime const start_time_; QTimer updater_; }; auto CreateCustomPlot() { QPointer<QCustomPlot> result = new QCustomPlot; for (int i = 0; i < 4; ++i) result->addGraph(); result->setMinimumSize(500, 300); return result; } int main(int argc, char* argv[]) { QApplication app(argc, argv); QVector plots = { CreateCustomPlot(), CreateCustomPlot(), CreateCustomPlot(), CreateCustomPlot(), }; auto* const updater = new QCustomPlotUpdater(plots); updater->start(); for (auto const& plot : plots) plot->show(); app.exec(); }
You could find the complete project files here: https://gist.github.com/another-ghasem/5052517283d14968339c4177b86181f0
I also tried compiling with: -fsanitize=undefined,thread
and it's report nothing.
- Compiler: Debian clang version 11.0.1-2~deb10u1
- OS: Debian Buster 4.19.235-1
- Qt: 5.15.2
- QCustomPlot: 2.1.0, released on March 29, 2021