Qt 【串口通信】跨线程导致问题及解决办法(对外接口定义)

说明

在Qt官方文档中提到,QSerialPort是不不支持跨线程调用的(Ps:在Qt中大部分是都不支持跨线程的)
可以通过Thread::moveToThread来实现定义和使用在同一线程。

部分代码

主线程中定义串口类

    QThread *thread1 =new QThread;
    QSharedPointer<serialportiml> impl = serialportiml::CreateSerialPortIml(cfg);
    QObject::connect(thread1, &QThread::started, impl.get(), &serialportiml::Init);
    QObject::connect(impl.get(), &serialportiml::destroyed, thread1, &QThread::quit);
    QObject::connect(thread1, &QThread::finished, thread1, &QThread::deleteLater);
    impl->moveToThread(thread1);
    thread1->start();

串口的初始化在serialportiml::Init()中实现

void serialportiml::Init()
{
    m_sptrSerialport = serialport::CreateSerialPort(m_setting);
    m_sptrSerialport->Open();
}
QSharedPointer<serialport> serialport::CreateSerialPort(const QSettings& setting)
{
    QSharedPointer<serialport> sptr = QSharedPointer<serialport>(new serialport());
    sptr->Init(setting);
    return sptr;
}
void serialport::Init(const QSettings& settings)
{
    m_ptrSerialPort = new QSerialPort(this);
    m_ptrSerialPort->setPortName(/*"COM8"*/settings.value("ladserport/portname","COM8").toString());/*settings.value("ladserport/portname","COM4").toString()*/
    m_ptrSerialPort->setBaudRate(settings.value("ladserport/baudrate",921600).toInt()/*921600*/);
    m_ptrSerialPort->setParity(QSerialPort::NoParity);
    m_ptrSerialPort->setDataBits(QSerialPort::Data8);
    m_ptrSerialPort->setStopBits(QSerialPort::OneStop);
}

通过impl->moveToThread(thread1);将impl对象放到thread1线程中执行。实现串口的QSerialPort类的定义和使用都在thread1中。

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt中,线程通信需要使用信号和槽机制。对于UDP socket的线程通信,可以按照以下步骤进行操作: 1. 创建一个继承自QObject的自定义类,用于处理UDP socket的相关操作。 ```cpp class UDPSocketHandler : public QObject { Q_OBJECT public: explicit UDPSocketHandler(QObject *parent = nullptr); // 其他成员函数和变量 signals: void dataReceived(QByteArray data); public slots: void sendData(QByteArray data); // 其他槽函数 }; ``` 2. 在UDPSocketHandler类中创建一个QUdpSocket对象,并在构造函数中进行初始化和绑定。 ```cpp UDPSocketHandler::UDPSocketHandler(QObject *parent) : QObject(parent) { // 创建并绑定socket QUdpSocket *socket = new QUdpSocket(this); socket->bind(QHostAddress::Any, 1234); // 绑定到本地IP和端口1234 // 将socket的readyRead信号与槽函数进行连接 connect(socket, &QUdpSocket::readyRead, this, [socket]() { QByteArray data; while (socket->hasPendingDatagrams()) { data.resize(socket->pendingDatagramSize()); socket->readDatagram(data.data(), data.size()); emit dataReceived(data); } }); } ``` 3. 在主线程中创建一个UDPSocketHandler对象,并通过信号和槽进行线程通信。 ```cpp int main(int argc, char *argv[]) { QApplication a(argc, argv); // 创建UDPSocketHandler对象 UDPSocketHandler udpHandler; // 创建UI窗口等代码... // 将UI的信号与udpHandler的槽函数进行连接 QObject::connect(&ui, &UIWidget::sendData, &udpHandler, &UDPSocketHandler::sendData); return a.exec(); } ``` 4. 在UI部分,通过信号槽机制将数据发送到UDPSocketHandler对象中,实现线程通信。 ```cpp class UIWidget : public QWidget { Q_OBJECT public: explicit UIWidget(QWidget *parent = nullptr); signals: void sendData(QByteArray data); private slots: void onSendButtonClicked() { QByteArray data = "Hello UDP!"; emit sendData(data); } }; ``` 通过以上步骤,可以实现在UI线程中发送数据到UDP socket所在的线程,并在该线程中接收数据。记得在.pro文件中添加`QT += network`来引入网络模块。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值