2011-07-20 64 views
1

我正在構建一個將嚴重依賴插件的應用程序:內核從串行接口獲取數據並將其傳遞給每個插件,以便每個插件都可以決定如何處理它。QPluginLoader移動到線程

我的設計允許插件構建一個通過QMdiSubWindow連接到MDIArea的Widget。 這工作,直到我需要互斥體,因爲一切都運行在同一個線程我非常快速死鎖。 所以我雖然移動每個插件到不同的線程可以解決這個問題。問題是(現在),QMdiSubWindow不再被創建,我不知道爲什麼會發生這種情況。

內核通過使用信號和插槽與插件進行通信。

這是我如何加載我的插件並將其移動到一個線程:

QPluginLoader loader(the_path); 
QObject* plugin = loader.instance(); 
if(plugin!=0) 
{ 
    //Connect install subwindows request 
    connect(plugin, SIGNAL(install_plugin_window(QString,QWidget*)), this, SLOT(onRequestInstallSubwindow(QString,QWidget*))); 

    QThread* consumer = new QThread; 
    plugin->moveToThread(consumer); 
    consumer->start(); 

    PluginInterface* pl = qobject_cast<PluginInterface*>(plugin); 
    pl->registerSubWindow(); 
} 

請注意,這是原代碼的簡化。 我採取了這一做法(移動我的插件線程)立足這篇文章http://www.christeck.de/wp/2010/10/23/the-great-qthread-mess/

registerSubWindow()是我的插件,創建插件的方法:

void PluginDrier::registerSubWindow() 
{ 
    widget = new Form(); 
    emit install_plugin_window("Plugin Widget", widget); 
} 

,其發射被逮住的信號由具有此插槽的核心,其將所生成的小部件註冊爲所提到的MdiSubWindow:

void MainWindow::onRequestInstallSubwindow(QString title, QWidget* content) 
{ 
    QMdiSubWindow* subwindow = ui->mdiArea->addSubWindow(content); 
    subwindow->setWindowTitle(title); 
    subwindow->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint |  Qt::WindowMinMaxButtonsHint); 
} 

回答

1

僅在GUI線程中工作的Qt小部件。您可能會嘗試將插件內部操作移至不同的線程,但所有GUI都必須保留在您的主線程中。

試試這個:

void PluginDrier::registerSubWindow() 
{ 
    widget = new Form(); 
    widget->moveToThread(QApplication::instance()->thread()); 
    emit install_plugin_window("Plugin Widget", widget); 
} 

,但我沒有測試它,可能無法正常工作。另外,請記住,如果我的解決方案可行,則內部邏輯和gui之間的所有通信都應該是線程安全的。

+0

我可以將小部件移動到onRequestInstallSubwindow()中的GUI線程中嗎? –

+0

問題是:鑑於小部件必須位於主線程中,在獨立線程中創建它們的價值是什麼?在我看來,將數據讀入另一個線程會更好,並將所有GUI操作保留在主線程中。 –

+0

我怎樣才能將我的插件分成兩部分?也許在我的插件中包含一個Worker Object,它將包含所有內部邏輯並將該Worker對象傳遞給新線程? –