QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread 问题解决

使用Qt的多线程时,出现 QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread 的错误。通过查询资料总结如下:

  1. 创建一个子线程对象是主线程的工作.也就是说在对象在哪个线程被实例化就属于哪个线程.
  2. 利用movetothread函数可以将对象转移至另外的线程.
  3. QThread的run函数属于子线程
  4. 信号和槽 隶属于它们所在对象的线程.
  5. 使用connect之后,槽函数默认执行在槽函数所在线程,若改变connect函数的第五个参数,比如设为Qt::DirectConnection,可让槽函数在信号所在线程执行.

根据以上的结论,代码报错的原因是:

  1. QUdpSocket对象在DataReceive的构造函数中被实例化,而DataReceive的实例化是被主线程实例化的,因此QUdpSocket也属于主线程,而QUdpSocket发出的socket通知是在主线程,对应的槽函数是在子线程.

原来的代码:

#pragma once

#ifndef DataReceive_h__
#define DataReceive_h__

#include 
#include 
#include "common.h"

class QUdpSocket;

class DataReceive  : public QObject
{ 
	Q_OBJECT

public:
	DataReceive(QObject *parent=nullptr);
	~DataReceive();

public slots:
	void slotReadyRead();
	void doInit();

signals:
	void sigCoilData(Coils_T coils);
	void sigSensorData(Sensors_T sensors);

private:
	QByteArray _recv();

private:
	QUdpSocket* m_pUdp = nullptr;
	QByteArray _cache;
	QByteArray _packet;
	Coils_T _cache_coils;
	Sensors_T _cache_sensors;

	std::vector _coils_mask{ 0,1,2,3,4,5,6,7,8,9 };
	std::vector _sensors_mask{ 0,1,2,3,4,5,6,7,8,9 };
};
#endif // DataReceive_h__


DataReceive::DataReceive(QObject *parent)
	: QObject(parent)
{
	m_pUdp = new QUdpSocket;
	m_pUdp->bind(QHostAddress::LocalHost, 244);
	//接收数据
	bool isR = connect(m_pUdp, &QUdpSocket::readyRead, this, &DataReceive::slotReadyRead);
}

更改后:

void DataReceive::doInit() {
	m_pUdp = new QUdpSocket;
	m_pUdp->bind(QHostAddress::LocalHost, 244);
	//接收数据
	bool isR = connect(m_pUdp, &QUdpSocket::readyRead, this, &DataReceive::slotReadyRead);
}

将DataReceive构造函数中初始化upd的代码放到了doInit中,该函数被

    QThread* t = new QThread;
    m_dataReceive->moveToThread(t);
    bool isB = connect(t, SIGNAL(started()), m_dataReceive, SLOT(doInit()));

started信号调用。

你可能感兴趣的:(杂记,java,开发语言)