I have an app with such structure: all the datatypes ( class INode
) are stored in plugins (DLLs). Some of the datatypes can be drawn (if they're IDrawable
).
To load an object of, eg class PointCloudNode: public INode
I have a special input plugin (DLL) which is called class PointCloudParser: public IIOPlugin
and IIOPlugin
is a thread with some specific functionality: class IIOPlugin: public QThread
.
All the objects are created by NodeFactory
class which is a singleton stored in separate DLL.
And here's the problem:
void PointCloudNode::update()
{
QObject::connect (this,SIGNAL(tmptmp()),this,SLOT(drawObject()));
emit tmptmp();
}
If I do this from any thread (main thread or the Input Plugin thread)
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();
The update launches, the tmptmp()
signal is emitted, and the slot ( drawObject()
) executes correctly.
if do just the same, but create the object in my Input Plugin, pass over the shared pointer and execute dr->update()
in another function, the slot drawObject()
is never entered though all the code is executed (including connect
, etc.). 如果执行相同的操作,但是在我的输入插件中创建对象,传递共享指针并在另一个函数中执行dr->update()
,尽管执行了所有代码(包括connect
drawObject()
却从未输入slot drawObject()
等)。
To be more precise, here's the Input Plugin:
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
}
The last emit is connected to this:
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 :(
}
How come? The node
object is the same all the way through, it is valid. Every line in code in launched, QObject::connect
doesn't write anything to debug window, the signal tmptmp()
is emitted, but the slot drawObject()
in one case is never reached? Any ideas?
If I do not inherit IIOPlugin
from QThread
, everything works fine (ie load the object in the main thread). 如果我没有从QThread
继承IIOPlugin
,那么一切都会很好(即,将对象加载到主线程中)。 I expected the signals/slots to work across the threads...
Since you are sending a signal across to a different thread, you might need to explicitly tell Qt that the connection should be a queued one:
QObject::connect(this, SIGNAL(tmptmp()), this, SLOT(drawObject()), Qt::QueuedConnection );
By default Qt will use Qt::AutoConnection
as that last parameter, and it will choose whether to use a direct connection (if the slot is in the same thread as the emitter) or a queued connection (if the slot is in a different thread). But since your thread is in a separate library, maybe Qt isn't making the right assumption here.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.