写一段QT6,操作串口的代码,要求界面显示和串口读取和数据处理是三个线程,界面显示配置串口,后开始启动读取串口任务,读取的串口数据交给再处理线程,处理线程将数据转成base64后发送给界面线程
时间: 2024-05-06 16:14:55 浏览: 240
以下是一个使用 QT6 操作串口的示例代码,其中包含界面显示、串口读取和数据处理三个线程:
```cpp
#include <QApplication>
#include <QThread>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>
class SerialPort : public QObject
{
Q_OBJECT
public:
SerialPort(QObject* parent = nullptr) : QObject(parent)
{
// 初始化串口
m_serialPort = new QSerialPort(this);
m_serialPort->setBaudRate(QSerialPort::Baud9600);
m_serialPort->setParity(QSerialPort::NoParity);
m_serialPort->setDataBits(QSerialPort::Data8);
m_serialPort->setStopBits(QSerialPort::OneStop);
}
~SerialPort()
{
// 关闭串口
if (m_serialPort->isOpen()) {
m_serialPort->close();
}
}
signals:
void dataReceived(const QByteArray& data);
public slots:
void open(const QString& portName)
{
// 打开串口
m_serialPort->setPortName(portName);
if (m_serialPort->open(QSerialPort::ReadWrite)) {
qDebug() << "Serial port " << portName << " opened.";
connect(m_serialPort, &QSerialPort::readyRead, this, &SerialPort::readData);
} else {
qDebug() << "Failed to open serial port " << portName << ".";
}
}
void close()
{
// 关闭串口
if (m_serialPort->isOpen()) {
m_serialPort->close();
disconnect(m_serialPort, &QSerialPort::readyRead, this, &SerialPort::readData);
qDebug() << "Serial port closed.";
}
}
void write(const QByteArray& data)
{
// 写数据到串口
if (m_serialPort->isOpen()) {
m_serialPort->write(data);
}
}
private:
QSerialPort* m_serialPort;
void readData()
{
// 读取串口数据并发送到数据处理线程
QByteArray data = m_serialPort->readAll();
emit dataReceived(data);
}
};
class DataProcessor : public QObject
{
Q_OBJECT
public:
DataProcessor(QObject* parent = nullptr) : QObject(parent)
{
}
signals:
void dataProcessed(const QByteArray& data);
public slots:
void processData(const QByteArray& data)
{
// 将数据转换成 base64 格式并发送到界面线程
QByteArray encodedData = data.toBase64();
emit dataProcessed(encodedData);
}
};
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget* parent = nullptr) : QWidget(parent)
{
// 创建界面控件
m_portComboBox = new QComboBox(this);
m_portComboBox->addItem(tr("Select a serial port"));
for (const QSerialPortInfo& portInfo : QSerialPortInfo::availablePorts()) {
m_portComboBox->addItem(portInfo.portName());
}
m_openButton = new QPushButton(tr("Open"), this);
m_closeButton = new QPushButton(tr("Close"), this);
m_textEdit = new QTextEdit(this);
// 布局
QHBoxLayout* buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(m_openButton);
buttonLayout->addWidget(m_closeButton);
QVBoxLayout* mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(m_portComboBox);
mainLayout->addLayout(buttonLayout);
mainLayout->addWidget(m_textEdit);
// 创建线程
m_serialPortThread = new QThread(this);
m_dataProcessorThread = new QThread(this);
// 创建对象并移动到线程中
m_serialPort = new SerialPort;
m_serialPort->moveToThread(m_serialPortThread);
m_dataProcessor = new DataProcessor;
m_dataProcessor->moveToThread(m_dataProcessorThread);
// 信号连接
connect(m_openButton, &QPushButton::clicked, this, &MainWindow::openSerialPort);
connect(m_closeButton, &QPushButton::clicked, this, &MainWindow::closeSerialPort);
connect(m_serialPort, &SerialPort::dataReceived, m_dataProcessor, &DataProcessor::processData);
connect(m_dataProcessor, &DataProcessor::dataProcessed, this, &MainWindow::updateText);
// 线程启动
m_serialPortThread->start();
m_dataProcessorThread->start();
}
~MainWindow()
{
// 停止线程并删除对象
m_serialPortThread->quit();
m_serialPortThread->wait();
m_dataProcessorThread->quit();
m_dataProcessorThread->wait();
delete m_serialPort;
delete m_dataProcessor;
}
private:
QComboBox* m_portComboBox;
QPushButton* m_openButton;
QPushButton* m_closeButton;
QTextEdit* m_textEdit;
QThread* m_serialPortThread;
QThread* m_dataProcessorThread;
SerialPort* m_serialPort;
DataProcessor* m_dataProcessor;
void openSerialPort()
{
// 打开串口
QString portName = m_portComboBox->currentText();
if (portName == tr("Select a serial port")) {
return;
}
m_serialPortThread->start();
QMetaObject::invokeMethod(m_serialPort, "open", Qt::QueuedConnection,
Q_ARG(QString, portName));
m_openButton->setEnabled(false);
m_closeButton->setEnabled(true);
}
void closeSerialPort()
{
// 关闭串口
QMetaObject::invokeMethod(m_serialPort, "close", Qt::QueuedConnection);
m_openButton->setEnabled(true);
m_closeButton->setEnabled(false);
}
void updateText(const QByteArray& data)
{
// 更新界面文本框
m_textEdit->append(data);
}
};
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MainWindow w;
w.show();
return app.exec();
}
#include "main.moc"
```
在上面的代码中,SerialPort 类表示串口操作的对象,DataProcessor 类表示数据处理的对象,MainWindow 类表示界面。在 MainWindow 的构造函数中,创建了界面控件,创建了两个线程和两个对象,并将对象移动到对应的线程中。在信号连接中,SerialPort 对象的 dataReceived 信号连接到 DataProcessor 对象的 processData 槽函数,DataProcessor 对象的 dataProcessed 信号连接到 MainWindow 对象的 updateText 槽函数。在 openSerialPort 函数中,使用 QMetaObject::invokeMethod 函数将打开串口的代码放入 SerialPort 对象所在线程的消息队列中,以保证串口操作在该线程中执行。在 closeSerialPort 函数中也使用了这种方式关闭串口。在 DataProcessor 对象的 processData 函数中,将收到的串口数据转换成 base64 格式并发送到界面线程。在 MainWindow 对象的 updateText 函数中,将收到的 base64 格式的数据转换成字符串并显示在界面文本框中。
阅读全文
相关推荐
![-](https://img-home.csdnimg.cn/images/20241231044955.png)
![-](https://img-home.csdnimg.cn/images/20241231045053.png)
![-](https://img-home.csdnimg.cn/images/20241231045053.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![-](https://img-home.csdnimg.cn/images/20241231045053.png)
![-](https://img-home.csdnimg.cn/images/20241231045053.png)
![-](https://img-home.csdnimg.cn/images/20241231045053.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)