前言:
对于一般的上位机开发,无论是使用QT还是C#,主要功能包含:1.接收并解析下位机上传的数据、2.打包并发送数据到下位机、3.业务逻辑,对数据实时显示到界面或者存储到数据库。从软件分层的角度来看,底层是数据层、中间是业务逻辑处理、上层是UI。
在处理大数据量时,为了不让界面假死或者卡顿,需要采用多线程的方式来实现。
1.抽象实现,建立模型
无论是QT/C#上位机,还是基于linux/nuttx…的APP,只要有需求,那就一定有实现需求的框架,这个框架就是对需求的抽象,建立需求的模型。
1.1 数据的来源:可以来自底层的设备、远程的下位机;本地的数据库;本地的进程。
1.2 数据的逻辑:收数据、解析数据;打包数据、发送数据;按照具体的业务处理数据。
1.3 数据的显示:基于linux/nuttx…shell终端;基于QT的ui(可以是曲线、数值等)。
以下就是应用程序的大概模型:
2.QT的多线程如何实现?
QT的多线程实现有两种方式:
1.继承QThread,重载run函数;
2.继承QObject,moveToThread(QThread *)。
两种方式都可以,但需要注意的是:重载run函数,只有run函数中的代码属于该线程;moveToThread(QThread *)时,整个继承QObject的对象都属于该线程。特别是使用signal/slot时尤其注意slot函数到底在那个线程执行?
建议采用方式2,使用更加灵活:这里实现了数据接收者类(硬件接口serial/udpSocket)。
在mainwindow.cpp中实例化数据接收者,再调用moveToThread(Thread ),实现了多线程。
1.dataRecieve.h
#ifndef DATARECIEVE_H
#define DATARECIEVE_H
#include <QObject>
#include <qobjectdefs.h>
#include <QtSerialPort/QtSerialPort>
#include <QSerialPortInfo>
#include <QQueue>
#include <QDebug>
#include <QHash>
#include <QColor>
#include <QByteArray>
#include <QUdpSocket>
#include <QTcpSocket>
#include <QHostAddress>
/* params struct */
struct params_t{
int a;
float b;
uint8_t c;
short d;
};
union payload_u{
uint8_t data[64];
struct params_t params;
};
/* message struct */
struct data_msg_t{
uint8_t head;
uint