[英]qt signals/slots in a plugin
我有一個具有這種結構的應用程序:所有數據類型( class INode
)都存儲在插件(DLL)中。 某些數據類型可以繪制(如果它們是IDrawable
)。
要加載例如class PointCloudNode: public INode
的對象,我有一個特殊的輸入插件(DLL),稱為class PointCloudParser: public IIOPlugin
而IIOPlugin
是具有某些特定功能的線程: 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()
,盡管執行了所有代碼(包括connect
drawObject()
卻從未輸入slot 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
,那么一切都會很好(即,將對象加載到主線程中)。 我希望信號/插槽可以跨線程工作...
由於您正在向另一個線程發送信號,因此您可能需要明確告訴Qt該連接應該是排隊的:
QObject::connect(this, SIGNAL(tmptmp()), this, SLOT(drawObject()), Qt::QueuedConnection );
默認情況下,Qt將使用Qt::AutoConnection
作為最后一個參數,它將選擇是使用直接連接(如果插槽與發射器在同一線程中)還是使用排隊連接(如果插槽在不同的線程中) )。 但是由於您的線程位於單獨的庫中,因此Qt在這里可能沒有做出正確的假設。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.