一、创建串口通信类和线程类,串口通信类(SerialPortClass)。首先,在QT项目中包含必要的头文件:
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
二、创建一个类来处理串口通信相关操作
class SerialPortClass
{
public:
SerialPortClass();
~SerialPortClass();
bool openSerialPort(const QString& portName, int baudRate);
void closeSerialPort();
qint64 writeData(const QByteArray& data);
qint64 readData(QByteArray& data);
private:
QSerialPort *serial;
};
SerialPortClass::SerialPortClass()
{
serial = new QSerialPort;
}
SerialPortClass::~SerialPortClass()
{
if (serial->isOpen())
serial->close();
delete serial;
}
bool SerialPortClass::openSerialPort(const QString& portName, int baudRate)
{
serial->setPortName(portName);
serial->setBaudRate(baudRate);
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
return serial->open(QIODevice::ReadWrite);
}
void SerialPortClass::closeSerialPort()
{
if (serial->isOpen())
serial->close();
}
qint64 SerialPortClass::writeData(const QByteArray& data)
{
if (serial->isOpen())
return serial->write(data);
return -1;
}
qint64 SerialPortClass::readData(QByteArray& data)
{
if (serial->isOpen())
return serial->read(data.data(), serial->bytesAvailable());
return -1;
}
三、线程类(SerialThread,创建一个继承自 QThread 的线程类来处理串口通信
#include <QThread>
class SerialThread : public QThread
{
Q_OBJECT
public:
SerialThread(const QString& portName, int baudRate);
~SerialThread();
protected:
void run() override;
signals:
void dataReceived(const QByteArray& data);
private:
SerialPortClass *serialPort;
QString portName;
int baudRate;
};
SerialThread::SerialThread(const QString& portName, int baudRate)
{
this->portName = portName;
this->baudRate = baudRate;
serialPort = new SerialPortClass;
}
SerialThread::~SerialThread()
{
if (serialPort)
{
serialPort->closeSerialPort();
delete serialPort;
}
}
void SerialThread::run()
{
if (serialPort->openSerialPort(portName, baudRate))
{
QByteArray buffer;
while (!isInterruptionRequested())
{
qint64 bytesRead = serialPort->readData(buffer);
if (bytesRead > 0)
{
emit dataReceived(buffer);
}
}
serialPort->closeSerialPort();
}
}
四、在主程序中使用线程进行串口通信。在主窗口类(例如 MainWindow)中包含头文件:
#include "serialthread.h"
五、在类定义中添加成员变量
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
SerialThread *serialThread;
};
六、在构造函数中初始化并启动线程
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
serialThread = new SerialThread("/dev/ttyUSB0", 9600);
connect(serialThread, &SerialThread::dataReceived, this, [](const QByteArray& data) {
// 在这里处理接收到的数据
qDebug() << "Received data: " << data;
});
serialThread->start();
}
MainWindow::~MainWindow()
{
if (serialThread)
{
serialThread->requestInterruption();
serialThread->wait();
delete serialThread;
}
}
在以上代码的示例中:
1.首先创建了一个专门处理串口通信的类 SerialPortClass,它封装了串口的打开、关闭、读写等操作。
2.然后创建了一个线程类 SerialThread,在线程的 run 方法中打开串口并不断读取数据,如果有数据可读就通过信号发射出去。
3.在主窗口类中创建了线程对象,连接了线程的数据接收信号到一个槽函数(这里使用了lambda表达式作为槽函数),用于处理接收到的数据,最后启动线程。当主窗口关闭时,请求线程中断并等待线程结束后再删除线程对象。
请注意: 上述代码中的串口名称(如 /dev/ttyUSB0)需要根据实际情况进行修改。 这里只是一个简单的示例,实际应用中可能需要更多的错误处理和功能扩展。