Search code examples
qtsignals-slotsqthreadqobjectqtcpsocket

QObject: Cannot create children for a parent that is in a different thread: parent's thread:QThread(0x221f650), current thread:QThread(0x23a7950)


I am trying to fetch data from device using QTCpSocket (telnet). After a lot of struggle I felt I overcame one issue that was Qtimer:starttimer can not be started from other thread.

But,now I have came across another issue which is confusing me a lot. I have gone through some post in internet but it's not helping me. Please go through my code and let me know my mistake

fdu.cpp

#include "fdu.h"
#include "ui_fdu.h"
#include"fduprocess.h"
fdu::fdu(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::fdu)
{
    ui->setupUi(this);
    QThread *workerThread =  new QThread;
    fduprocess *worker = new fduprocess;

 qDebug()<< "...goind to fduprocess........";
    workerThread->start();
    worker->_ReconnectionTimerInstance.setSingleShot(true);
    worker->_ReconnectionTimerInstance.start(1000);
    worker->_iStatusPollTimer = startTimer(500);
    worker->moveToThread(workerThread);
    connect(workerThread,SIGNAL(started()),worker,SLOT(tryit()));
    connect(workerThread,SIGNAL(finished()),worker,SLOT(deleteLater()));

}

fdu::~fdu()
{
    delete ui;
}

fduprocess.cpp

#include "fduprocess.h"
#include<QDebug>
#include<QThread>
fduprocess::fduprocess(QObject *parent) : QObject(parent)
{

}

void fduprocess::timerEvent(QTimerEvent *event)
{
    if(event->timerId()== _iStatusPollTimer)
    {

        if(_ClientSocketInstance.state() == QAbstractSocket::ConnectedState)
        {
            _ClientSocketInstance.write("alarmstat\r\n"); //25
             _ClientSocketInstance.write("selectedin\r\n"); // 4
              _ClientSocketInstance.write("sigoutstat\r\n"); //13
           _ClientSocketInstance.write("disablestat\r\n"); //5

           _ClientSocketInstance.write("pwrstat\r\n"); //5

           _ClientSocketInstance.write("siginstat\r\n");//5
        }
    }
}

void fduprocess::tryit()
{
 qDebug()<< "...came inside tryit to tryit.........";
 connect(&_ReconnectionTimerInstance,SIGNAL(timeout()), this, SLOT(when_ReconnectionTimer_timeout()));
  qDebug()<< "...conencted to whentimeout.........";
 connect(&_ClientSocketInstance,SIGNAL(connected()), this, SLOT(when_ClientSocketInstance_connected()));
 connect(&_ClientSocketInstance,SIGNAL(disconnected()), this, SLOT(when_ClientSocketInstance_disconnected()));
 connect(&_ClientSocketInstance,SIGNAL(readyRead()), this, SLOT(when_ClientSocketInstance_readyRead()));
 connect(&_ClientSocketInstance,SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(when_ClientSocketInstance_error(QAbstractSocket::SocketError)));
 _strIPAddress = "192.168.1.135";
 _usiPort = 23;
  qDebug()<< "...end tryit........";


}

void fduprocess::doOntimeout()
{
    qDebug()<< "................";
}

void fduprocess::when_ReconnectionTimer_timeout()
{
    qDebug()<<"Reconnecting..";
      // qDebug()<< _ClientSocketInstance.children();
        _ClientSocketInstance.connectToHost(_strIPAddress, _usiPort);
}

void fduprocess::when_ClientSocketInstance_connected()
{ qDebug()<<"Connected......";

    _ClientSocketInstance.write("endrun_1");
    _ClientSocketInstance.flush();
    _ClientSocketInstance.write("\n");
    _ClientSocketInstance.write("\n");
    _ClientSocketInstance.write("\n");
    _ClientSocketInstance.flush();

}

void fduprocess::when_ClientSocketInstance_disconnected()
{
    qDebug()<<"Disconnected";
        _ReconnectionTimerInstance.start();
}

void fduprocess::when_ClientSocketInstance_readyRead()
{
    QByteArray get = _ClientSocketInstance.readLine();
    qDebug() << get ;
}

void fduprocess::when_ClientSocketInstance_error(QAbstractSocket::SocketError error)
{

}

Any other feedback regarding any other code smells will be highly welcomed Please ignore my indentation and naming conventions,since I am in my learning curve. Here is the console output :

...goind to fduprocess........
...came inside tryit to tryit.........
...conencted to whentimeout.........
...end tryit........
Reconnecting..
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTcpSocket(0x609250), parent's thread is QThread(0x221f650), current thread is QThread(0x23a7950)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTcpSocket(0x609250), parent's thread is QThread(0x221f650), current thread is QThread(0x23a7950)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTcpSocket(0x609250), parent's thread is QThread(0x221f650), current thread is QThread(0x23a7950)

Solution

  • When you create worker, the object and all its members are created in the main thread. Then, you move worker to its own thread, which moves all its children QObjects. All slots in worker will now be executed on this new thread.

    From fduprocess constructor, it looks like you don't give a parent to your socket (_ClientSocketInstance). That means the socket is not moved to the same thread as the worker but stays in the main thread, which gives this warning when you use it from a slot. If you pass this to _ClientSocketInstance constructor to make it a child of worker, it will automatically be moved to the same thread as worker and the warning should disappear.