Я видел много сообщений и статей о QThread и перемещении QObject между QThreads, но, увы, это все еще вызывает у меня головную боль. Это шаблон, который я пытаюсь принять:
#include "connectionthread.h"
#include <cassert>
ConnectionThread::ConnectionThread(ConnectionPtr const &connectionPtr) :
worker(NULL),
m_connectionPtr(connectionPtr)
{
connect(this, SIGNAL(executeSignal()), this, SLOT(loginProcess()));
}
void
ConnectionThread::start()
{
if(worker) {
if(worker->isRunning()) {
worker->quit();
}
delete worker;
}
worker = new QThread;
connect(worker, SIGNAL(started()), this, SLOT(run()));
worker->start();
}
void
ConnectionThread::run()
{
emit executeSignal();
}
void
ConnectionThread::loginProcess()
{
m_connectionPtr->Connect();
}
Теперь экземпляр этого создается в основном потоке графического интерфейса, но когда, наконец, вызывается loginProcess, он блокируется до завершения, что приводит к зависанию графического интерфейса моего приложения. Обратите внимание: никакой разницы не наблюдается, если я помещаю логический код непосредственно в функцию запуска и опускаю сигнал, как показано ниже:
void
ConnectionThread::run()
{
m_connectionPtr->Connect();
}
Итак, я предположил, что мне нужно переместить «это» в поток с именем worker, что-то вроде:
void
ConnectionThread::start()
{
if(worker) {
if(worker->isRunning()) {
worker->quit();
}
delete worker;
}
worker = new QThread;
this->moveToThread(worker);
connect(worker, SIGNAL(started()), this, SLOT(run()));
worker->start();
}
но это дает мне
QObject: Cannot create children for a parent that is in a different thread.
Однако я не уверен, почему это так, поскольку создается экземпляр ConnectionThread, и его функция запуска вызывается из другого потока. Давайте назовем этот другой поток GuiThread. Это означает, что GuiThread имеет контроль, поэтому должен иметь возможность передать право собственности на экземпляр ConnectionThread рабочему потоку.
И последняя возможность, которую я еще не исследовал полностью, — это возможность перемещения m_connectionPtr в рабочий поток.
Любые мысли о приведенном выше шаблоне, как я могу его улучшить и вообще, как я могу предотвратить его блокировку?