Qt---多线程绘制折线图

Qt多线程绘制折线图

需求:在ui中绘制折线图,需要在子线程中操作ui界面上的对象。因为子线程中创建图形化相关的不被允许,因此【思路1:】在子线程中仅仅读取数据,进行数据处理,将数据处理的结果返回给主线程,主线程操作ui界面进行绘制折线图。【思路2:】将ui界面的控件使用指针传递的方式直接传递给子线程使用,子线程中进行数据处理,处理完毕绘制折线图。(实际操作中,折线图需要customplot->replot()之后才会自动更新到ui界面上,否则需要人为的用鼠标在ui的相对应的绘图控件上点击或者滚动滑轮才可显示图像,但是子线程不允许此代码,因此需要使用信号和槽在主线程中执行此句代码。)

  • Qt多线成使用的是将继承于QObject的对象moveToThread到QThread对象中的方法
  • 绘图使用的是qCustomPlot第三方库

代码如下

  • my_task.h
#ifndef MY_TASK_H
#define MY_TASK_H

#include <QObject>
#include "qcustomplot.h"

class My_Task : public QObject
{
   
    Q_OBJECT
public:
    explicit My_Task(QObject *parent = nullptr);
 

signals:

 
     void task_0_signals(QCustomPlot* customplotOnThread);//使用的是主线程ui上的customPlot
     void task_draw0End_signal();//发送绘图结束信号
     void task_draw1End_signal(QCustomPlot *customPlot);
     void task_draw2End_signal(QVector<double> ticksVector,
                               QVector<double> valuesVector,
                               double maxX,
                               double maxY,
                               QColor color);

public slots:
    void task_draw0(QCustomPlot *customPlot,QCPGraph* graph,QCPGraph* graph1);
    void task_draw1();
    void task_draw2();

  void on_filePath_signal(QString filePath);


private:
    QCustomPlot *customPlot;
    QCPAxis *keyAxis;
    QCPAxis *valueAxis;
    QCPGraph *graph0 = nullptr;

    QString filePathName;
};

#endif // MY_TASK_H

  • my_task.cpp


#include "my_task.h"
#include "unistd.h"


My_Task::My_Task(QObject *parent) : QObject(parent)
{
   

}
 
/**
 * @brief My_Task::task_draw0
 * @param customPlot
 * 要从主线程的ui界面中传递customplot控件过来在子线程中调用,将主线程的graph对象传递
 * 过来,
 */
void My_Task::task_draw0(QCustomPlot *customPlot,QCPGraph* graph,QCPGraph* graph1)
{
   
    customPlot->setNoAntialiasingOnDrag(true);
    keyAxis = customPlot->xAxis;
    valueAxis = customPlot->yAxis;


 
//    graph0 = new QCPGraph(keyAxis,valueAxis);//子线程中新建图形化相关的对象报错

    QFile file(filePathName);
    QTextStream stream(&file);
   bool isOK = file.open(QIODevice::ReadOnly| QIODevice::Text);
   if(!isOK){
   

       qDebug()<<"文件打开失败";
     return;
   }

     QString str;
     //QVector<QString> strVector;
     QVector<double> amplitudeVector,phaseVector;
     while(!stream.atEnd()){
   
       str = stream.readLine();

       amplitudeVector<<str.section(" ",0,0).toDouble();
       phaseVector<<str.section(" ",1,1).toDouble();

     }

     QVector<double> ticksVector0,dataVector0,ticksVector1,dataVector1;

   dataVector0 = amplitudeVector;
   dataVector1 = phaseVector;
  int maxX = dataVector0.count();
  int maxY0 = 0,maxY1 = 0,maxY = 0;
     for(int i=0;i<dataVector0.count();i++){
   
          ticksVector0 << i;
          ticksVector1 << i;
          if(maxY0 <dataVector0.at(i))
              maxY0 = dataVector0.at(i);
          if(maxY1 <dataVector1.at(i))
              maxY1 
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要实现Qt接收数据实时显示并绘制折线图,可以参考以下步骤: 1. 创建一个主窗口,添加一个QCustomPlot控件用于绘制折线图。 2. 在主窗口中创建一个Qtimer对象,用于定时更新数据。 3. 在Qtimer的槽函数中,读取串口数据并更新折线图。 4. 在QCustomPlot控件的初始化函数中,设置x和y轴范围、坐标轴标签等属性。 5. 在更新折线图的槽函数中,先将新的数据添加到QVector容器中,再将容器中的数据绘制折线图。 下面是一个简单的代码示例,仅供参考: ``` // 主窗口类 class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void updateData(); // 定时更新数据的槽函数 void plotGraph(); // 绘制折线图的槽函数 private: Ui::MainWindow *ui; QSerialPort *serialPort; // 串口对象 QTimer *timer; // 定时器对象 QVector<double> xData, yData; // 数据容器 }; // 构造函数 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // 创建串口对象 serialPort = new QSerialPort(this); serialPort->setPortName("COM1"); serialPort->setBaudRate(QSerialPort::Baud9600); serialPort->setDataBits(QSerialPort::Data8); serialPort->setStopBits(QSerialPort::OneStop); serialPort->setParity(QSerialPort::NoParity); serialPort->open(QIODevice::ReadOnly); // 创建定时器对象 timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(updateData())); timer->start(100); // 每100ms更新一次数据 // 初始化QCustomPlot控件 ui->plot->addGraph(); ui->plot->graph(0)->setPen(QPen(Qt::blue)); ui->plot->xAxis->setLabel("Time"); ui->plot->yAxis->setLabel("Value"); ui->plot->xAxis->setRange(0, 10); ui->plot->yAxis->setRange(0, 100); } // 析构函数 MainWindow::~MainWindow() { delete ui; } // 定时更新数据的槽函数 void MainWindow::updateData() { QByteArray data = serialPort->readAll(); // 处理数据... plotGraph(); // 更新折线图 } // 绘制折线图的槽函数 void MainWindow::plotGraph() { double x = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0; // 获取当前时间 double y = 50; // 假设读取到的数据为50 xData.append(x); yData.append(y); // 绘制折线图 ui->plot->graph(0)->setData(xData, yData); ui->plot->replot(); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值