I'm building an application that will rely heavily on plugins: the core gets data from a serial interface and delivers it to each plugin so each one can decide what to do with it.
My design allows the plugins to build a Widget that is attached to a MDIArea through a QMdiSubWindow. This worked until I needed mutexes, as everything was running in the same thread I got deadlocks very fast. So I though that moving each plugin to a different thread could solve this. The problem is that (for now), the QMdiSubWindow are not being created anymore and I have no clue why this is happening.
The core communicates with plugins by using signals and slots.
This is how I load my plugins and move them into a thread:
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();
}
Please note that this is a simplification of the original code. I followed this approach (moving my plugin to a thread) basing on this article http://www.christeck.de/wp/2010/10/23/the-great-qthread-mess/
registerSubWindow() is the method in my plugin that creates the widget:
void PluginDrier::registerSubWindow()
{
widget = new Form();
emit install_开发者_如何学Cplugin_window( "Plugin Widget", widget );
}
Which emits a signal that is catched by the core with this slot, which registers the generated widget as the mentioned 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 );
}
Qt widgets working only in the GUI thread. You may try to move plugin inner operations to different threads, but all GUI must remain in your main thread.
Try this:
void PluginDrier::registerSubWindow()
{
widget = new Form();
widget->moveToThread(QApplication::instance()->thread ());
emit install_plugin_window( "Plugin Widget", widget );
}
but i haven't test it, may not work. Also, keep in mind that all communications between your inner logic and the gui should be thread-safe if my solution would work.
精彩评论