Qt线程爬坑2-QObject moveToThread后,报QSocketNotifier: Socket notifiers cannot be enabled or disabled from

2 篇文章 0 订阅
本文详细介绍了在Qt项目中遇到的QWebSocket在多线程环境中使用时引发的问题,即QSocketNotifier错误。问题在于QWebSocket对象在主线程创建,但在其他线程中接收消息。解决方案是在工作线程的run方法内实例化QWebSocket,确保创建和使用在同一线程。通过这样的调整,成功避免了跨线程操作QWebSocket导致的错误。
摘要由CSDN通过智能技术生成

问题描述

在项目中需要打开麦克风并将麦克风的数据用WebSocket送到讯飞上进行识别,很自然的新建一个类继承QObject,然后定义一个QWebSocket的 成员变量,然后在这个类的构造函数里示例化这个QWebSocket,最后moveToThread

但是当QWebSocket收到消息却报QSocketNotifier: Socket notifiers cannot be enabled or disabled from another threa.

尝试将QWebSocket的实例化放到moveToThread后,发现还是报错。

原因

查阅资料发现和继承QThread一样,这个类是在主线程上实例化的,所以是和主类在同一个线程。moveToThread只是改变了此对象及其子类的线程关联关系(描述不太准确),当该线程启动的时候,对应的方法才是在这个线程中运行(继承QThread则是在run方法),但是其他方法依旧还是在主类同一个线程。

回到问题,在线程启动后,QWebSocket对象是在这个线程中接收消息,但是这个对象是在主线程创建的。在Qt中是不可以在不同的线程中操纵QWebSocket的.(又或者说创建QSocketNotifier和使用QSocketNotifier不在同一个线程是不允许,但是没找到官方文档说这样不允许,而且也没找到QSocketNotifierQWebSocket的关系 待深入理解)

https://stackoverflow.com/questions/47449312/qobject-cannot-create-children-for-a-parent-that-is-in-a-different-thread

https://stackoverflow.com/questions/3268073/qobject-cannot-create-children-for-a-parent-that-is-in-a-different-thread

https://stackoverflow.com/questions/36065240/using-qtcpsockets-through-different-threads

解决

在新建类的构造函数中将QWebSocket对象初始化为nullptr, 然后在对应的槽函数(QThread的是run函数)中实例化

/*---------------------------------------MainWindow.cpp-------------------------------------------------------------*/
connect(m_thread, &QThread::started, m_worker, &Worker::run);
/*------------------------------------Worker.cpp----------------------------------------------------------------------*/
Worker::Worker() : m_websocket(nullptr)
{

}


void Worker::run()
{
  if (m_websocket == nullptr)
  {
    m_websocket = new QWebSocket();
    connect(m_websocket, &QWebSocket::connected, this, [this](){
        ......
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值