QObject сделан в QThread, теряет внутренний сигнал / соединения слотов - PullRequest
0 голосов
/ 27 ноября 2011

У меня есть рабочий QThread, в котором создается производный объект QObject.Объект представляет собой совокупность двух других QObject производных объектов, поэтому существуют внутренние соединения для связывания сигналов и связывания двух внутренних объектов.

Рабочий QThread является членом QPlugin, поэтому присутствует в течение всего времени жизни плагина.

Проблема, с которой я столкнулся, заключается в том, что хотя объект прекрасно взаимодействует с остальной частью приложения, эти внутренние соединения, похоже, разорваны.В качестве эксперимента я попытался создать объект в основном потоке, и внутренние соединения функционируют, поэтому я определенно что-то не так делаю с QThread s.

Я также попытался переместить объект обратно восновной поток (по общему признанию после того, как те внутренние соединения сделаны), но это не имело никакого эффекта.Я перебирал все типы соединений (Direct, Queued и т. Д.) Для внутренних соединений, но это либо не имело эффекта, либо вызывало ошибки взаимоблокировки.Все типы, передаваемые через соединения, зарегистрированы.

Объект является родителем QObject двух содержащихся объектов, это не должно иметь значения, поскольку все они находятся в одном потоке, но я попытался установитьих родитель для NULL только для того, чтобы исключить это - не удивительно.QThread является , а не родительским для чего-либо.

Единственное, в чем я не уверен, это то, что объект создан из фабричного синглтона, который находится в главном потоке, новызывается из рабочего потока - так кому он принадлежит?Я в полной растерянности относительно того, что я делаю (или не делаю), чтобы разорвать эти связи, поэтому любая помощь очень ценится.Вот код в соответствующих частях приложения:

Это вызов создания объекта в рабочем потоке, для контекста объект является поли-сеткой из OBJ импортера.

//  Create mesh.
QString type = Sy::plugMeshType + "Sy_polyMesh";
QString name = proj->newNameIncrement( "objMesh" );

Sy::PluginArgs args; args << name;
Sy_polyMesh* obj = Sy_pluginLoader::createInstance< Sy_polyMesh >( type, args );
obj->mesh() = mesh;
obj->resizeBB();
result_ = obj;

//  If in GUI mode, register it with the project.
if ( gui_ ) {
    proj->registerSimObject( obj );
    proj->selectObject( obj );
}

У меня достаточно обширная архитектура плагинов для моего приложения, поэтому фактический начальный код потока абстрагируется в абстрактный рабочий класс:

void Sy_abstractLongProcess::begin( Sy_abstractLongProcessWorker* worker )
{
    worker_ = worker;
    worker_->moveToThread( &thread_ );

    QObject::connect( &thread_, SIGNAL( started() ), worker_, SLOT( work() ) );

    QObject* thisObj = dynamic_cast< QObject* >( this );

    QObject::connect( &thread_, SIGNAL( finished() ), worker_, SIGNAL( finished() ) );
    QObject::connect( worker_, SIGNAL( finished() ), thisObj, SIGNAL( finished() ) );
    QObject::connect( worker_, SIGNAL( progressChanged( double ) ), thisObj, SIGNAL( progressChanged( double ) ) );
    QObject::connect( worker_, SIGNAL( finished() ), &thread_, SLOT( quit() ) );

    thread_.start();
}

Как все соответствующий код распределен по многимзанятия, я не буду перечислять все (этот вопрос достаточно длинный), но если вам нужно увидеть что-то еще, не стесняйтесь спрашивать - мне нужна вся помощь, которую я могу получить по этому вопросу.

1 Ответ

0 голосов
/ 28 ноября 2011

У меня почти был ответ в исходном посте, когда я пытался переместить объект обратно в главный поток, только я сделал это слишком рано. Мне пришлось отодвинуть его назад после завершения изменений, которые необходимо было выполнить в рабочем потоке - теперь это очевидно!

Спасибо Мату за то, что он помог мне разобраться

...