PDA

View Full Version : [QTcpSocket] Cannot create children for a parent that is in a different thread



SteveJ
25th January 2016, 16:46
Hello,
I'm new to Qt and I have this project where I am trying to connect the signal of a thread to another new one, when it is created.
I am working with Qt 5.2.1 .
I get the following Error as soon as "spreadData" is emitted:
Cannot create children for a parent that is in a different thread. Parent is QNativeSocketEngine... Parents thread is MyThread... Current thread is QThread...

MyServer.cpp:

void MyServer::incomingConnection(qintptr socketDescriptor)
{
MyThread *thread = new MyThread(socketDescriptor, this);

connect(thread, SIGNAL(sendData(QByteArray)),this,SLOT(getData(QBy teArray)));
connect(this,SIGNAL(spreadData(QByteArray)),thread ,SLOT(writeData(QByteArray))); //Error occurring here

connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

thread->start();
}


void MyServer::getData(QByteArray Data)
{
if(!Data.isNull())
{
emit spreadData(Data);
}
}



MyThread.cpp:

void MyThread::run()
{
socket = new QTcpSocket();

connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()),Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));

exec();
}



QByteArray MyThread::getData()
{
return this->Data;
}


void MyThread::writeData(QByteArray newData)
{
socket->write(newData);
}

I have been searching a long time for a solution but couldn't find any, so please help me. Thanks

anda_skoa
25th January 2016, 17:13
Your MyThread instance is in a different thread than the "socket" instance it contains but you are calling the socket's write method without any thread change.

Cheers,
_

SteveJ
26th January 2016, 09:47
Could you please tell me how?
I tried using movetothread() and changing my signals&slots but I could not figure it out...

anda_skoa
26th January 2016, 10:13
You could send the data to an object that lives in the second thread, e.g. connecting a signal of MyThread to a slot of such an object and emitting that from MyThread::writeData() or calling that slot via QMetaObject::invokeMethod.

Alternatively you could split MyThread into a normal QObject subclass that provides the API you connect to and move that into a plain QThread instance.

Alternatively you could try thread->moveToThread(thread) and not pass "this" to the MyThread constructor

Cheers,
_

SteveJ
26th January 2016, 14:25
Alternatively you could try thread->moveToThread(thread) and not pass "this" to the MyThread constructor
_

This was the easiest way to fix it for me. Thank you !!! :)