天天看点

qt跨线程 调用 QSerialPortQSerialPort 跨线程思路代码测试结果

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
-----------------------------------------------------------------------------------
           

继续阅读