前言
整体逻辑:
(1)ui->setupUi(this)主程序里CAN采集数据,10ms采集一次。
(2)CAN帧处理,将CAN帧里的数据分类处理,1s的CAN帧(100个)放入各自的数组里。
(3)数组传输到新建的线程class里。
(4)传输完成后,启动线程,线程里将接收到的数组进行绘图。
问题解释:
(1)为啥CAN帧分类处理:CAN帧组成为各个变量组成的集合,仅仅是一系列的数据。CAN帧中必须加入报头,接收后以报头为基准,才能根据传输协议将各个数据分离出来,然后处理。
(2)为啥数组必须传输到另一个线程,不能在主程序里直接处理:plot绘图消耗时间,使得CAN帧接收不稳定,定时器线程也不能正常工作。
第一部分:不同class之间数据传输
写在前面:网上查阅很多方法,有用emit的,有直接全局变量的,验证之后感觉能用但是其方法很麻烦,采用最简单的方法,并且好理解的方式才是最好的。
第一步:这个是基础,在ui->setupUi(this)主程序里,告诉主程序有个线程。这个是开线程后必须写的,做什么都方便。其中datadeal是开的线程的c文件的名字和class的名字,具体的可以参照前文。
mythread = new datadeal(this);
第二步:主函数mainwindow的h文件里,声明list,当然之前肯定先添加list头文件。
#include <QList>
public:
QList<uint16_t> list_ms;
第三步:主函数的c文件里,初始化list
list_ms.clear();
第四步:调用发送函数。这个函数在你自己的主函数里调用,我的在定时器函数里面调用。首先将数据放入list中,采用append函数。放进去之后就发送。list没有上限,随便放。这里的recv函数还没有定义,需要下一步定义。这里先说是为了逻辑清晰。
list_ms.append(gnFirFrame_ms[gnDataBufferCnt]);
mythread->recvListData_ms(list_ms);
第五步:在新的class里面,也就是新开的线程的h文件里面定义槽函数
public slots:
void recvListData_ms(QList<uint16_t> list);
第六步:处理函数,在你新线程里面c文件里。这样主程序里执行函数,这里就会执行。就会将list里面的数据传输给定义的gnshow数组里了,当然你自己定义数组也可以。
void datadeal::recvListData_ms(QList<uint16_t> list)
{
for(int i=0;i<100;i++)
{
gnShowFrame_ms[i] = list.at(i);
}
}
第七步:验证,在里面搞个debug,观察传输的数据就可以了,验证后发现传输的数据都是对的。
注:里面的数据类型必须对应,处理函数数组里的100必须和放list的数据个数append的相等,不然会报错。
第二部分:总结
规律总结一下:(1)主函数必须定义新类的函数,见第一步;(2)主文件h必须定义需要传输的数据,见第二步;(3)主文件c必须数据放入和调用新类的函数,见第四步;(4)新类的h文件定义槽函数,也就是主文件里调用的函数,见第五步;(5)新类的c文件里槽函数主体,见第六步。
参考了很多函数,主函数和其他子函数,或者新类的传输,等等,都是这一个套路,类与类之间的调用也是这样,定义,调用,定义,槽函数。就这几步。
注:由于小伙伴需要源代码的时间不同,登录邮箱界面太多麻烦,所以建立了一个订阅号,如果有问题或者需要源码,可添加订阅号,留言后会发送源代码或者有任何问题可留言,将积极解决提出的问题。