您的位置:首页 > 文旅 > 旅游 > 今天刚刚长沙又增加了一例_抖音竞价推广怎么做_手机推广平台有哪些_互联网媒体广告公司

今天刚刚长沙又增加了一例_抖音竞价推广怎么做_手机推广平台有哪些_互联网媒体广告公司

2024/12/23 7:44:26 来源:https://blog.csdn.net/weixin_39723539/article/details/144556041  浏览:    关键词:今天刚刚长沙又增加了一例_抖音竞价推广怎么做_手机推广平台有哪些_互联网媒体广告公司
今天刚刚长沙又增加了一例_抖音竞价推广怎么做_手机推广平台有哪些_互联网媒体广告公司

这里介绍的是moveToThread的方式,继承QThread的方式可以参考我的另一篇文章【嵌入式——QT】QThread创建多线程

编程实现

首先创建一个类,但是这个类一定要继承QObject
SerialWorker.h

#ifndef SERIALWORKER_H
#define SERIALWORKER_H#include <QObject>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QThread>
#include <QQueue>
#include <QTimer>class SerialWorker : public QObject
{Q_OBJECT
public:SerialWorker(QObject *parent = nullptr);~SerialWorker();void setProperties(qint32 baudRate, QSerialPort::DataBits dataBits,QSerialPort::Parity parity, QSerialPort::StopBits stopBits,QSerialPort::FlowControl flowControl);void setPortName(QString name);void setStop(bool isStop = true);public slots:void openSerialPort();void closeSerialPort();void writeData(const QByteArray &data);void readData();void handleSerialError(QSerialPort::SerialPortError error);QByteArray readDataDelay();void process();void handleReadTimeout();signals:void dataReceived(const QByteArray &data, QString curCmd);void errorOccurred(const QString &error);public:QQueue<QString> cmdQueue;QTimer *qtimer = NULL;QTimer *readTimeout = NULL;private:QSerialPort *serialPort = NULL;QString portName;QByteArray sumData;QString curCmd;bool isStop = false;
};#endif // SERIALWORKER_H

SerialWorker.cpp

#include "SerialWorker.h"
#include <QDebug>//指令头
#define PROTOCOL_STX 0xFF
//指令尾
#define PROTOCOL_ETX 0xFESerialWorker::SerialWorker(QObject *parent): QObject(parent)
{serialPort = new QSerialPort(this);connect(serialPort, &QSerialPort::readyRead, this, &SerialWorker::readData);connect(serialPort, &QSerialPort::errorOccurred, this, &SerialWorker::handleSerialError);qtimer = new QTimer(this);connect(qtimer, &QTimer::timeout, this, &SerialWorker::process);qtimer->start(100);readTimeout = new QTimer(this);readTimeout->setSingleShot(true); // 只触发一次超时connect(readTimeout, &QTimer::timeout, this, &SerialWorker::handleReadTimeout);}SerialWorker::~SerialWorker()
{if (serialPort->isOpen()) {serialPort->close();}delete serialPort;delete qtimer;delete readTimeout;
}void SerialWorker::setProperties(qint32 baudRate, QSerialPort::DataBits dataBits, QSerialPort::Parity parity,QSerialPort::StopBits stopBits, QSerialPort::FlowControl flowControl)
{serialPort->setBaudRate(baudRate);serialPort->setDataBits(dataBits);serialPort->setParity(parity);serialPort->setStopBits(stopBits);serialPort->setFlowControl(flowControl);}void SerialWorker::setPortName(QString name)
{this->portName = name;
}void SerialWorker::process()
{if (!serialPort->isOpen()) {qDebug() << "Serial port is not open!";return;}// qDebug() << "process";// while(!isStop) {//     QThread::msleep(500);if(!cmdQueue.isEmpty()) {QString cmd = cmdQueue.dequeue();curCmd = cmd;writeData(cmd.toUtf8());} else {cmdQueue.enqueue("1 sts\n");// QThread::msleep(100);cmdQueue.enqueue("2 sts\n");}// }
}void SerialWorker::handleReadTimeout()
{emit errorOccurred("Read data error");cmdQueue.clear();
}void SerialWorker::setStop(bool isStop)
{this->isStop = isStop;
}void SerialWorker::openSerialPort()
{serialPort->setPortName(portName);if (!serialPort->open(QIODevice::ReadWrite)) {qDebug() << "Serial port faile";} else {qDebug() << "Serial port opened";}
}void SerialWorker::closeSerialPort()
{if (serialPort->isOpen()) {serialPort->close();qDebug() << "Serial port closed";}
}void SerialWorker::writeData(const QByteArray &data)
{// qDebug() << "writeData" << QThread::currentThreadId();if (serialPort->isOpen()) {if(data.contains("1 sts\n") || data.contains("2 sts\n")) {} else {qDebug() << "writeData" << data;}if(serialPort->write(data) > 0) {readTimeout->start(2000);}}
}void SerialWorker::readData()
{// qDebug() << "readData" << QThread::currentThreadId();QByteArray recvData = serialPort->readAll();// qDebug() << "recvData" << recvData;if (!recvData.isEmpty()) {sumData.append(recvData);unsigned char firstByte = static_cast<unsigned char>(sumData[0]);unsigned char lastByte = static_cast<unsigned char>(sumData[sumData.size() - 1]);//判断指令头指令尾是否正确if (lastByte == PROTOCOL_ETX && firstByte == PROTOCOL_STX) {if (readTimeout->isActive()) {readTimeout->stop(); // 停止超时定时器}// qDebug() << "sumData" << sumData.toHex().toUpper();emit dataReceived(sumData, curCmd);sumData.clear();}}}/*
QSerialPort::ResourceError: 串口设备意外断开。
QSerialPort::DeviceNotFoundError: 找不到设备(通常在尝试打开不存在的串口时)。
QSerialPort::ReadError: 读取数据时发生错误。
QSerialPort::WriteError: 写入数据时发生错误。
*/
void SerialWorker::handleSerialError(QSerialPort::SerialPortError error)
{qDebug() << "error" << error;if (error == QSerialPort::ResourceError) {// qDebug() << "Serial port disconnected!";emit errorOccurred("Serial port disconnected");closeSerialPort();  // 关闭串口,清理资源} else if(error == QSerialPort::DeviceNotFoundError) {emit errorOccurred("Device not found");} else if(error == QSerialPort::ReadError) {emit errorOccurred("Read data error");} else if(error == QSerialPort::WriteError) {emit errorOccurred("Write data error");}}QByteArray SerialWorker::readDataDelay()
{int retryCount = 0;QByteArray data;while(retryCount <= 10) {if(serialPort->waitForReadyRead(500)) {QByteArray recvData = serialPort->readAll();if (!recvData.isEmpty()) {data.append(recvData);unsigned char firstByte = static_cast<unsigned char>(data[0]);unsigned char lastByte = static_cast<unsigned char>(data[data.size() - 1]);//判断指令头指令尾是否正确if (lastByte == PROTOCOL_ETX && firstByte == PROTOCOL_STX) {qDebug() << "data" << data.toHex().toUpper();return data;}}} else {retryCount++;}}return QByteArray();
}

在主线程中创建线程实例

QThread *workerThread = new QThread(this);

将我们上面创建的类移动到线程中去执行,这样之后在这个类中执行的所有方法,都将是在子线程中执行的,主线程和子线程之间可以通过信号槽的方式来进行通信。

serialWorker->moveToThread(workerThread);

当然将这个工作类移动到子线程之后,还是需要将这个线程启动的,需要调用QThread的start函数来进行启动,表示这个线程启动了,你之后调用的方法都是在这个子线程中执行的。

workerThread->start();

也可以在子线程中编写死循环一直使其去执行,然后绑定个信号,在子线程启动的时候触发这个槽函数

QThread *workerThread = new QThread(this);
connect(workerThread, &QThread::started, serialWorker, &SerialWorker::process);//子线程槽函数
void SerialWorker::process()
{while(!isStop) {QThread::msleep(500);//逻辑处理}
}

其实这种写法在子线程中编写死循环是存在问题的,会导致其他的函数在主线程中无法调用,所以这种方式最好不要使用死循环的方式来实现,如果想要编写死循环的话,可以在按照同样的方式重新创建一个线程,或者使用继承QThread的方式来实现。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com