簡體   English   中英

插件中的qt信號/插槽

[英]qt signals/slots in a plugin

我有一個具有這種結構的應用程序:所有數據類型( 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() ,盡管執行了所有代碼(包括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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM