qt多线程绘制动态曲线
时间: 2025-03-21 12:15:46 浏览: 90
如何在 Qt 中使用多线程绘制动态曲线
使用 QCustomPlot 和多线程实现动态曲线绘制
为了实现在 Qt 中通过多线程绘制动态曲线的功能,可以结合 QCustomPlot
库和 Qt 的多线程机制。以下是具体的技术细节:
QCustomPlot 集成
QCustomPlot 是一个用于数据可视化的强大工具[^1]。它能够高效地处理大量数据点,并提供丰富的绘图选项。要将其集成到项目中,需下载其源码文件并将头文件和.cpp
文件添加至工程。多线程设计
在 Qt 中创建多线程可以通过继承QThread
或者利用信号槽机制来完成[^3]。对于动态曲线的绘制,通常会将耗时的数据采集或计算逻辑放在独立的工作线程中运行,而主线程负责 GUI 更新。工作流程分解
- 数据生成/采集:由子线程定期更新一组新的数值。
- 曲线刷新:当接收到新数据后,在主线程调用
replot()
方法重绘图表。
代码示例 下面是一个简单的例子展示如何设置一个多线程环境以持续向主窗口发送随机数序列作为输入值来进行动态曲线显示。
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "qcustomplot.h"
#include "mythread.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void updateGraph(double value);
private:
Ui::MainWindow *ui;
MyThread* m_thread; // 自定义线程类实例化对象指针
};
#endif // MAINWINDOW_H
// mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
class MyThread : public QThread
{
Q_OBJECT
signals:
void newSampleReady(double sample);
protected:
void run() override;
};
#endif // MYTHREAD_H
// 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 "mythread.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 初始化自定义线程并启动之
m_thread = new MyThread(this);
connect(m_thread,SIGNAL(newSampleReady(double)),this,SLOT(updateGraph(double)));
m_thread->start();
// 设置初始图形参数
ui->customPlot->addGraph(); // 添加一条默认折线图
ui->customPlot->graph(0)->setPen(QColor(Qt::blue));
ui->customPlot->xAxis->setLabel("Time");
ui->customPlot->yAxis->setLabel("Value");
QVector<double> timeData, valueData;
ui->customPlot->graph(0)->setData(timeData,valueData);
}
void MainWindow::updateGraph(double value){
static int counter=0;
QVector<double> x,y;
// 获取当前已有数据集副本
x = ui->customPlot->graph(0)->data()->keys().toVector();
y = ui->customPlot->graph(0)->data()->values().toVector();
if(x.size()>50){ // 控制最大保留历史记录长度为50帧
x.erase(x.begin());
y.erase(y.begin());
}
x.append(++counter);
y.append(value);
ui->customPlot->graph(0)->setData(x,y);
ui->customPlot->rescaleAxes();
ui->customPlot->replot(); // 刷新整个视图区域
}
MainWindow::~MainWindow()
{
delete ui;
if (m_thread != nullptr && m_thread->isRunning()) {
m_thread->quit(); // 安全退出线程循环体
m_thread->wait(); // 主动等待直到完全销毁资源释放完毕再继续下一步操作
}
}
// mythread.cpp
#include "mythread.h"
#include <QRandomGenerator>
#include <QThread>
void MyThread::run(){
qsrand((uint)QDateTime::currentMSecsSinceEpoch());
while(true){
emit newSampleReady(static_cast<double>(qrand())/RAND_MAX*100); // 发送模拟采样结果给外部接收方监听器函数回调接口处执行后续业务逻辑处理动作
msleep(100); // 每隔一定间隔时间触发一次事件通知消息队列里排队等候响应状态机调度安排好优先级顺序之后才允许真正进入临界区访问共享变量修改内存地址空间内容结构布局形式发生变化情况下的同步互斥锁保护措施防止竞争条件发生死锁现象等问题出现影响程序稳定性可靠性性能指标等方面造成不可预估损失风险隐患存在可能性较大因此需要特别注意这一点非常重要!!!
}
}
上述代码展示了基本框架下如何构建基于 Qt 平台上的跨平台应用程序开发过程中涉及到的一些核心概念和技术要点[^2]。
相关推荐


















