2011-07-20 2 views
1

Je construis une application qui dépendra fortement des plugins: le noyau récupère les données d'une interface série et les délivre à chaque plugin pour que chacun puisse décider quoi en faire.QPluginLoader déplacé vers le thread

Mon design permet aux plugins de construire un widget attaché à un MDIArea via un QMdiSubWindow. Cela a fonctionné jusqu'à ce que j'ai besoin de mutex, comme tout fonctionnait dans le même fil, j'ai eu des blocages très rapides. Donc, je pense que déplacer chaque plug-in à un thread différent pourrait résoudre ce problème. Le problème est que (pour l'instant), les QMdiSubWindow ne sont plus créés et je n'ai aucune idée de pourquoi cela se produit.

Le noyau communique avec les plugins en utilisant des signaux et des emplacements.

Voici comment je charge mes plugins et de les déplacer dans un fil:

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(); 
} 

S'il vous plaît noter que ceci est une simplification du code d'origine. J'ai suivi cette approche (déplacer mon plugin à un fil) se basant sur cet article http://www.christeck.de/wp/2010/10/23/the-great-qthread-mess/

registerSubWindow() est la méthode dans mon plug-in qui crée le widget:

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

qui émet un signal qui est attrapée par le noyau avec cette fente, qui enregistre le widget comme le produit mentionné 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); 
} 

Répondre

1

widgets Qt travaillant uniquement dans le fil de l'interface graphique. Vous pouvez essayer de déplacer les opérations internes du plugin vers différents threads, mais toute l'interface graphique doit rester dans votre thread principal.

Essayez ceci:

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

mais je ne le tester, peut ne pas fonctionner. Aussi, gardez à l'esprit que toutes les communications entre votre logique interne et l'interface graphique doivent être thread-safe si ma solution fonctionne.

+0

Pourrais-je déplacer le widget vers le thread d'interface graphique dans onRequestInstallSubwindow() mieux? –

+0

La question est: étant donné que les widgets doivent être dans le thread principal, quelle est la valeur de les créer dans des threads séparés? Il me semble qu'il vaudrait mieux déplacer votre lecture de données dans un thread différent, et garder toutes vos opérations GUI dans le principal. –

+0

Comment puis-je séparer mes plugins en deux parties? Peut-être inclure un objet de travail dans mon plugin, qui contiendrait toute la logique interne et transférer cet objet de travail au nouveau thread? –

Questions connexes