QPluginLoader移动到线程

时间:2011-07-20 09:37:23

标签: qt qthread

我正在构建一个严重依赖插件的应用程序:核心从串行接口获取数据并将其传递到每个插件,以便每个人都可以决定如何处理它。

我的设计允许插件构建一个通过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 个答案:

答案 0 :(得分:1)

Qt小部件仅在GUI线程中工作。您可以尝试将插件内部操作移动到不同的线程,但所有GUI必须保留在主线程中。

试试这个:

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

但我没有测试过,可能无法正常工作。另外,请记住,如果我的解决方案有效,内部逻辑和gui之间的所有通信都应该是线程安全的。