QSerialPort 跨線程思路
建立類thread_test_class 繼承object類 在其内部建立QSerialPort 和綁定接受槽函數
在主線程中建立thread_test_class 和建立 qthred 對象 将thread_test_class 移動到子線程中,注意在子線程中希望對外開發的槽函數在連接配接信号量時需要添加直接連接配接選項
//對外開放的子線程操作槽函數必須Qt::DirectConnection 可跨線程待用
connect(ui->pushButton_2, SIGNAL(clicked()), thread_test_dev, SLOT(write_data()), Qt::DirectConnection);
代碼
thread_test_class.h
#ifndef THREAD_TEST_CLASS_H
#define THREAD_TEST_CLASS_H
#include <QObject>
#include <QSerialPort> //提供通路序列槽的功能
class thread_test_class : public QObject {
Q_OBJECT
public:
explicit thread_test_class(QObject *parent = nullptr);
QSerialPort *port;
QString port_name;
void init_port(QString poart_name);
signals:
public slots:
void run();//子線程run
void rec_data();//序列槽接收
void write_data();//序列槽發送
};
#endif // THREAD_TEST_CLASS_H
thread_test_class.cpp
#include "thread_test_class.h"
#include <qDebug>
#include <QThread>
thread_test_class::thread_test_class(QObject *parent) : QObject(parent) {
port = new QSerialPort();
}
void thread_test_class::run() {
qDebug() << "thread_test_class 子線程 is:" << QThread::currentThreadId();
}
//序列槽初始化
void thread_test_class::init_port(QString poart_name) {
port->setPortName(poart_name);
port->setBaudRate(921600);
port->setDataBits(QSerialPort::Data8);
port->setParity(QSerialPort::NoParity);
port->setStopBits(QSerialPort::OneStop);
port->setFlowControl(QSerialPort::NoFlowControl);
if(port->open(QIODevice::ReadWrite)) {
qDebug() << "Port have been opened";
} else {
qDebug() << "open it failed";
}
//綁定接受槽函數
connect(this->port, SIGNAL(readyRead()), this, SLOT(rec_data()));
}
//接受槽函數
void thread_test_class::rec_data() {
QByteArray data = port->readAll();
qDebug() << "data received:" << data;
qDebug() << "thread_test_class is:" << QThread::currentThreadId();
}
//寫槽
void thread_test_class::write_data() {
qDebug() << "write_id is:" << QThread::currentThreadId();
port->write("data", 4);
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QThread>
#include <QNetworkInterface>
#include "thread_test_class.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
QThread *thread_test_;
thread_test_class *thread_test_dev;
private:
Ui::MainWindow *ui;
void check_uart();//序列槽檢測
signals:
void thread_start();//啟動線程槽
public slots:
void open_seril_slots();//打開線程槽
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow) {
ui->setupUi(this);
check_uart();//序列槽名檢測
qDebug() << "主線程 is:" << QThread::currentThreadId();
ui->pushButton_open_serial_state->setStyleSheet("background: rgb(255,0,0)");
//綁定打開序列槽槽
connect(ui->pushButton_open_serial, SIGNAL(clicked()), this, SLOT(open_seril_slots()));
}
void MainWindow::thread_star() {
thread_test_ = new QThread();
thread_test_dev = new thread_test_class();
thread_test_dev->init_port(ui->comboBox_serial_name->currentText());
thread_test_dev->moveToThread(thread_test_);
//對外開放的子線程操作槽函數必須Qt::DirectConnection 可跨線程待用
connect(ui->pushButton_2, SIGNAL(clicked()), thread_test_dev, SLOT(write_data()), Qt::DirectConnection);
//通過信号量啟動子線程
connect(this, SIGNAL(thread_start()), thread_test_dev, SLOT(run()));
thread_test_->start();
emit thread_start();
}
void MainWindow:: thread_stop() {
thread_test_->quit();
thread_test_->wait();
delete thread_test_;
delete thread_test_dev;
}
void MainWindow::open_seril_slots() {
if(ui->pushButton_open_serial->text() == "打開") {
ui->pushButton_open_serial_state->setStyleSheet("background: rgb(0,255,0)");
ui->pushButton_open_serial->setText("關閉");
thread_star();
} else {
ui->pushButton_open_serial_state->setStyleSheet("background: rgb(255,0,0)");
ui->pushButton_open_serial->setText("打開");
thread_stop() ;
}
}
MainWindow::~MainWindow() {
delete ui;
}
void MainWindow::check_uart() {
//通過QSerialPortInfo查找可用序列槽
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
ui->comboBox_serial_name->addItem(info.portName());
}
}
測試結果
主線程 is: 0x5d8 --->主線程ID
Port have been opened
-----------------------------------------------------------------------------------
thread_test_class 子線程 is: 0x1ee0 --->子線程ID
-----------------------------------------------------------------------------------
data received: "1234567890" --->接受槽所在 線程ID
thread_test_class is: 0x1ee0
-----------------------------------------------------------------------------------
write_id is: 0x5d8 --->發送槽所在 線程ID
-----------------------------------------------------------------------------------