Search code examples
c++multithreadingqtasynchronousqnetworkaccessmanager

QObject: Cannot create children for a parent that is in a different thread


EDIT:

I tried doing what you guys told me in comments ... :

Citizen * c = new Citizen(this);

QThread thread;
c->moveToThread(&thread);

connect(&thread, SIGNAL(started()), c, SLOT(ProcessActions()));
thread.start();

This produces even more errors:

QThread: Destroyed while thread is still running
ASSERT failure in QThread::setTerminationEnabled(): "Current thread was not started with QThread.", file c:\ndk_buildrepos\qt-desktop\src\corelib\thread\qthread_win.cpp, line 542
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
QObject::killTimers: timers cannot be stopped from another thread

I am having problems with this error ... I'm stuck on this for 2 days already and can't get a solution.

Header:

class Citizen : public QThread
{
Q_OBJECT    
    QNetworkAccessManager * manager;

private slots:
    void onReplyFinished(QNetworkReply* net_reply);

public:
    Citizen(QObject * parent);

    void run();
};

Implementation:

Citizen::Citizen(QObject * parent)
{
    manager = new QNetworkAccessManager;
    connect(_net_acc_mgr, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(onReplyFinished(QNetworkReply*)));
}

void Citizen::onReplyFinished(QNetworkReply* net_reply)
{
    emit onFinished(net_reply);
}

void Citizen::run()
{
    manager->get(QNetworkRequest(QUrl("http://google.com"));

    QEventLoop eLoop;
    connect(manager, SIGNAL( finished( QNetworkReply * ) ), &eLoop, SLOT(quit()));
    eLoop.exec(QEventLoop::ExcludeUserInputEvents);

    qDebug() << "loaded google!";

    exec();
}

When manager->get() gets executed, I get the following error:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNetworkAccessManager(0xc996cf8), parent's thread is QThread(0xaba48d8), current thread is Citizen(0xca7ae08)

When eLoop.exec() gets executed:

QObject::startTimer: timers cannot be started from another thread

I start this thread in the following manner:

Citizen * c = new Citizen(this);
c->start();

Why does this happen? How to solve this?


Solution

  • I will just try to answer why you are seeing QThread: Destroyed while thread is still running error.

    If you do this

    void mtMethod () {
    
     Citizen * c = new Citizen(this);
     QThread thread;
     c->moveToThread(&thread);
    
     connect(&thread, SIGNAL(started()), c, SLOT(ProcessActions()));
     thread.start();
    }
    

    The thread object will be destroyed when you exit the function but the thread that has been started is still running !. Qt is warning you that you should either stop the thread or create the thread object in a bigger scope. (i.e make it a member function of your class). Something like this :

    class myClass
    {
    virtual ~myClass ();
     QThread mythread;
    };
    
    myClass::~myClass
    {
      mythread.stop ();
    }
    
    void myClass::mtMethod () {
    
         Citizen * c = new Citizen(this);
         c->moveToThread(&mythread);
    
         connect(&mythread, SIGNAL(started()), c, SLOT(ProcessActions()));
         mythread.start();
    }