c++ - 插件中的 qt 信号/插槽

标签 c++ qt boost signals-slots

我有一个具有这种结构的应用程序:所有数据类型(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->update(),插槽 drawObject() 虽然执行了所有代码(包括 connect 等),但从未输入。

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

 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,一切正常(即在主线程中加载对象)。我希望信号/槽跨线程工作...

最佳答案

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

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

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

关于c++ - 插件中的 qt 信号/插槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3222307/

相关文章:

qt - Ubuntu 的原生 gui 工具包,过去、现在和 future

c++ - bjam 找不到 boost 库

c++模板参数编译器无法推断

c++ - PoCo 日志记录。包含创建时间戳的日志文件名或每次应用程序启动时的新日志文件

c++ - 转换 XOR 函数以返回 char* 而不是 string

c++ - 是否可以包装 C 风格的回调,以便您可以将 C++ lambda 与它们一起使用?

c++ - CRTP 和唯一持久标识符

qt - 如何在不缩放笔宽的情况下在 QGraphicsScene 上绘图?

c++ - 从 C++ 应用程序启动 Linux 服务时避免套接字继承

qt - 错误的坐标白色获取项目相对于其父项的真实位置