У меня есть рабочий QThread
, в котором создается производный объект QObject
. Объект представляет собой совокупность двух других QObject
производных объектов, поэтому существуют внутренние соединения для связывания сигналов и связывания двух внутренних объектов вместе.
Рабочий QThread
является членом QPlugin
, поэтому присутствует на протяжении всего времени существования плагина.
У меня проблема в том, что хотя объект нормально взаимодействует с остальной частью приложения, эти внутренние соединения, похоже, разорваны. В качестве эксперимента я попытался создать объект в основном потоке, и внутренние соединения работают, так что это определенно что-то, что я делаю неправильно с QThread
s.
Я также попытался переместить объект обратно в основной поток (правда, после того, как эти внутренние соединения были выполнены), но это не дало никакого эффекта. Я перебирал все типы соединений (прямые, очереди и т. д.) для внутренних соединений, но это либо не имело никакого эффекта, либо вызывало ошибки взаимной блокировки. Все типы, проходящие через соединения, регистрируются.
Объект является родителем 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();
}
Поскольку весь соответствующий код разбросан по многим классам, я не буду перечислять все (этот вопрос достаточно длинный), но если вам нужно увидеть что-то еще, не стесняйтесь спрашивать - мне нужно все помощь, которую я могу получить на этом.