基于QT的上位机多线程设计模型

您所在的位置:网站首页 上位机是什么软件 基于QT的上位机多线程设计模型

基于QT的上位机多线程设计模型

2024-03-16 08:08| 来源: 网络整理| 查看: 265

前言: 对于一般的上位机开发,无论是使用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 #include #include #include #include #include #include #include #include #include #include #include /* 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; uint8_t addr; uint8_t cmd; uint8_t length; union payload_u payload; uint8_t checksum; }; class dataRecieve : public QObject { Q_OBJECT public: /* constructor function */ dataRecieve(int type); /* set socket ip address and port */ bool setIp(); bool setPort(int port); bool setSerialName(QString name); signals: /* when get completly a message, emit the signal*/ void dataPush(struct data_msg_t *data_msg); private slots: /* 1.read raw data form socket or serial * 2.decode raw data to data_msg_t * 3.emit the signal:dataPush() */ void dataRecieveSlots(); void dataReadAll(); private: /* network */ QUdpSocket *UdpSocket; QTcpSocket *TcpSocket; int udpListenPort; public: /* serial */ QSerialPort *serial; QString serialName; /* configure the serial params */ bool configSerial(); }; #endif // DATARECIEVE_H

2…dataRecieve.cpp

#include "datarecieve.h" #include "qdebug.h" #include /* * constructor function * 1.select the interface type * 2.new the object */ dataRecieve::dataRecieve(int type) { if(type == 0){ /* connect */ //serial = new QSerialPort(); //QObject::connect(serial,&QSerialPort::readyRead,this,&dataRecieve::dataReadAll); qDebug() setDataBits(QSerialPort::Data8); //set parity serial->setParity(QSerialPort::NoParity); //set stopBits serial->setStopBits(QSerialPort::OneStop); //set flowcontrol serial->setFlowControl(QSerialPort::NoFlowControl); QObject::connect(serial,&QSerialPort::readyRead,this,&dataRecieve::dataReadAll); return true; }else{ return false; } } bool dataRecieve::setSerialName(QString name) { serialName = name; return true; } /* * decode raw data */ void dataRecieve::dataRecieveSlots() { char buffer[1024]; data_msg_t data_msg; configSerial(); while(true) { memset(buffer,0,sizeof(buffer)); //1.block: read data form socket or serial serial->waitForReadyRead(3000); serial->read(buffer,1024); //2.decode: raw data to data_msg_t memcpy(&data_msg.payload.data[0],&buffer[0],64); //3.emit the signal:dataPush emit dataPush(&data_msg); //4.debug qDebug() = 4){ data_msg.payload.data[0] = buff.at(0); data_msg.payload.data[1] = buff.at(1); data_msg.payload.data[2] = buff.at(2); data_msg.payload.data[3] = buff.at(3); //3.emit the signal:dataPush emit dataPush(&data_msg); //4.debug qDebug() moveToThread(sendThread); datarecieve->moveToThread(recieveThread); /* * connect function * inter-thread conmunication: signals/slots */ QObject::connect(this,SIGNAL(send_data(int)),datasend,SLOT(dataSendSlots(int)),Qt::QueuedConnection); QObject::connect(this,SIGNAL(recieve_data()),datarecieve,SLOT(dataRecieveSlots()),Qt::QueuedConnection); QObject::connect(datarecieve,SIGNAL(dataPush(struct data_msg_t *)),this,SLOT(recieve_msg_Data(struct data_msg_t *)),Qt::QueuedConnection); sendThread->start(); recieveThread->start(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_recieve_released() { if(datarecieve->setSerialName("/dev/ttyUSB0")){ emit recieve_data(); } qDebug() textBrowser_recieve->insertPlainText(" "); //2.save the data to database //3.show the data to curve //4.debug qDebug()


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3