QPluginLoader перемещен в поток - PullRequest
1 голос
/ 20 июля 2011

Я создаю приложение, которое будет в значительной степени зависеть от плагинов: ядро ​​получает данные от последовательного интерфейса и передает их каждому плагину, чтобы каждый мог решить, что с ним делать.

Мой дизайн позволяетплагины для создания виджета, который подключен к MDIArea через QMdiSubWindow.Это работало до тех пор, пока мне не понадобились мьютексы, поскольку все работало в одном потоке, и я очень быстро зашел в тупик.Поэтому я решил, что перемещение каждого плагина в другой поток может решить эту проблему.Проблема в том, что (на данный момент) 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 Ответ

1 голос
/ 20 июля 2011

Виджеты Qt работают только в потоке графического интерфейса. Вы можете попытаться переместить внутренние операции плагина в разные потоки, но весь графический интерфейс должен оставаться в вашем основном потоке.

Попробуйте это:

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

но я не проверял, может не работать. Кроме того, помните, что все коммуникации между вашей внутренней логикой и графическим интерфейсом должны быть поточно-ориентированными, если бы мое решение работало.

...