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不在同一个线程是不允许,但是没找到官方文档说这样不允许,而且也没找到QSocketNotifier和QWebSocket的关系 待深入理解)
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](){
......
}
}
}




