2010-07-11 45 views
1

我有這樣的結構的應用程序插槽:所有的數據類型(class INode)被存儲在插件(DLL)的。一些數據類型可以繪製(如果它們是IDrawable)。QT信號/在一個插件

要加載例如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())正確執行。

如果做一樣的,但創建我的輸入插件對象,越過共享指針,雖然執行的所有代碼(包括connect在另一個函數執行dr->update(),插槽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 
} 

最後EMIT連接到這一點:

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,一切正常(即加載主線程中的對象)。我所期望的信號/插槽跨線程工作...

+0

你做完了嗎,qmake,乾淨的,再做一次? – 2010-07-11 08:11:22

+0

*你有沒有在插件的源代碼中包含這最後一行? (Q_EXPORT_PLUGIN2(XXX,XXX)) – 2010-07-11 08:13:25

+0

是的,我已經做了所有該 的,似乎有什麼地方錯了的DLL之間的信號/插槽.. – Mikhail 2010-07-11 15:48:53

回答

0

因爲你是跨到不同的線程發送信號,你可能需要明確地告訴Qt的連接應是一個排隊的一個:

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

默認的Qt將使用Qt::AutoConnection作爲最後一個參數,它會選擇是否使用直接連接(如果插槽是在同一個線程中發射器)或排隊連接(如果插槽是在不同的線程)。但既然你的線程在一個單獨的庫中,也許Qt在這裏沒有做出正確的假設。