首页 文章

插件中的qt信号/插槽

提问于
浏览
1

我有一个具有这种结构的应用程序:所有数据类型( class INode )都存储在插件(DLL)中 . 可以绘制一些数据类型(如果它们是 IDrawable ) .

加载例如的对象 class PointCloudNode: public INode 我有一个特殊的输入插件(DLL),名为 class PointCloudParser: public IIOPluginIIOPlugin 是一个具有某些特定功能的线程: class IIOPlugin: public QThread .

所有对象都是由 NodeFactory class创建的,这是一个存储在单独DLL中的单例 .

这是问题所在:

void PointCloudNode::update()
{
QObject::connect (this,SIGNAL(tmptmp()),this,SLOT(drawObject()));
emit tmptmp();
}

如果我从任何线程(主线程或输入插件线程)执行此操作

NodeFactory* fab = NodeFactory::getInstance();
boost::shared_ptr<INode> pc(fab->createNode("pointCloud","myPC"));
boost::shared_ptr<IDrawable> dr = boost::dynamic_pointer_cast<IDrawable>(pc);
dr->update();

更新启动,发出 tmptmp() 信号,插槽( drawObject() )正确执行 .

BUT 如果做同样的事情,但是在我的输入插件中创建对象,传递共享指针并在另一个函数中执行 dr->update() ,虽然执行了所有代码(包括 connect 等),但从不输入插槽 drawObject() .

更确切地说,这是输入插件:

void PointCloudParserPlugin::doLoad(const QString& inputName, boost::shared_ptr<INode> container)
 {
   NodeFactory* factory = NodeFactory::getInstance();
   boost::shared_ptr<INode> node = factory->createNode("pointCloud", inputName);

   // here goes the loading itself, nothing special...

   container->addChild(node); //that's the container where I keep all the objects

   //boost::dynamic_pointer_cast<IDrawable>(container->getChild(inputName))->update();
   //If I uncomment this line, it all works: the slot is launched.  
   emit loadingFinished(inputName); // it executes the following function
 }

最后一个发射与此连接:

void GeomBox::updateVisualization(const QString& fileName)
 {
   boost::shared_ptr<INode> node = container_->getChild(fileName);
   boost::shared_ptr<IDrawable> nodeDrawable = boost::dynamic_pointer_cast<IDrawable>(node);
   nodeDrawable->update(); //this is the problem line: update() executes, connect() works, but the slot never runs :(
 }

怎么会? node 对象在所有过程中都是相同的,它是有效的 . 在启动的代码中的每一行, QObject::connect 都没有向调试窗口写入任何内容,发出信号 tmptmp() ,但是在一个案例中的插槽 drawObject() 永远不会到达?有任何想法吗?

Upd.: 如果我没有从 QThread 继承 IIOPlugin ,一切正常(即在主线程中加载对象) . 我希望信号/插槽可以跨线程工作......

1 回答

  • 0

    由于您要将信号发送到另一个线程,因此您可能需要明确告诉Qt连接应该是排队的:

    QObject::connect(this, SIGNAL(tmptmp()), this, SLOT(drawObject()), Qt::QueuedConnection );
    

    默认情况下,Qt将使用 Qt::AutoConnection 作为最后一个参数,它将选择是使用直接连接(如果插槽与 Launcher 位于同一个线程中)还是排队连接(如果插槽位于不同的线程中) . 但是由于你的线程在一个单独的库中,也许Qt没有在这里做出正确的假设 .

相关问题