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

问题描述

在项目中需要打开麦克风并将麦克风的数据用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](){
        ......
    }
  }
}

© 版权声明

相关文章

暂无评论

none
暂无评论...