【问题标题】:qt signals/slots in a plugin插件中的 qt 信号/插槽
【发布时间】:2010-07-11 08:00:11
【问题描述】:

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

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

所有对象均由NodeFactory 类创建,该类是存储在单独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()) 正确执行。

但是 如果做同样的事情,但是在我的输入插件中创建对象,传递共享指针并在另一个函数中执行dr-&gt;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()?有什么想法吗?

更新:如果我不从QThread 继承IIOPlugin,一切正常(即在主线程中加载对象)。我希望信号/插槽能够跨线程工作......

【问题讨论】:

  • 你完成了吗,qmake,make clean,make all again?
  • * 您是否在插件源代码中包含了最后一行? (Q_EXPORT_PLUGIN2(xxx,XXX))
  • 是的,我已经完成了所有这一切,似乎 DLL 之间的信号/插槽有问题..
  • 您是否仔细检查过插件是否已加载?在插件加载代码上添加一些断言
  • 是的,所有插件都加载正确。

标签: c++ qt boost signals-slots


【解决方案1】:

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

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

默认情况下,Qt 将使用Qt::AutoConnection 作为最后一个参数,它会选择是使用直接连接(如果插槽与发射器在同一个线程中)还是使用队列连接(如果插槽在不同的线程)。但是由于您的线程在一个单独的库中,所以 Qt 在这里可能没有做出正确的假设。

【讨论】:

    猜你喜欢
    • 2012-09-11
    • 2016-10-07
    • 1970-01-01
    • 2020-10-01
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    相关资源
    最近更新 更多