QPluginLoader dipindahkan ke utas

Saya sedang membangun sebuah aplikasi yang akan sangat bergantung pada plugin: inti mendapatkan data dari antarmuka serial dan mengirimkannya ke setiap plugin sehingga masing-masing dapat memutuskan apa yang harus dilakukan dengannya.

Desain saya memungkinkan plugin untuk membuat Widget yang dilampirkan ke MDIArea melalui QMdiSubWindow. Ini berhasil sampai saya membutuhkan mutex, karena semuanya berjalan di thread yang sama, saya mendapat kebuntuan dengan sangat cepat. Jadi menurut saya memindahkan setiap plugin ke utas yang berbeda dapat menyelesaikan masalah ini. Masalahnya adalah (untuk saat ini), QMdiSubWindow tidak dibuat lagi dan saya tidak tahu mengapa hal ini terjadi.

Inti berkomunikasi dengan plugin menggunakan sinyal dan slot.

Inilah cara saya memuat plugin saya dan memindahkannya ke dalam 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();
}

Harap dicatat bahwa ini adalah penyederhanaan dari kode aslinya. Saya mengikuti pendekatan ini (memindahkan plugin saya ke thread) berdasarkan artikel ini http://www.christeck.de/wp/2010/10/23/the-great-qthread-mess/

registerSubWindow() adalah metode di plugin saya yang membuat widget:

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

Yang memancarkan sinyal yang ditangkap oleh inti dengan slot ini, yang mendaftarkan widget yang dihasilkan sebagai MdiSubWindow yang disebutkan:

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

person Pherrymason    schedule 20.07.2011    source sumber


Jawaban (1)


Widget Qt hanya berfungsi di thread GUI. Anda dapat mencoba memindahkan operasi bagian dalam plugin ke thread yang berbeda, tetapi semua GUI harus tetap berada di thread utama Anda.

Coba ini:

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

tapi saya belum mengujinya, mungkin tidak berhasil. Juga, perlu diingat bahwa semua komunikasi antara logika batin Anda dan gui harus aman jika solusi saya berhasil.

person Raiv    schedule 20.07.2011
comment
Bisakah saya memindahkan widget ke thread GUI di onRequestInstallSubwindow() dengan lebih baik? - person Pherrymason; 20.07.2011
comment
Pertanyaannya adalah: mengingat widget harus berada di thread utama, apa gunanya membuatnya di thread terpisah? Menurut saya akan lebih baik untuk memindahkan pembacaan data Anda ke thread lain, dan menjaga semua operasi GUI Anda di thread utama. - person Dan Milburn; 20.07.2011
comment
Bagaimana saya bisa memisahkan plugin saya menjadi dua bagian? Mungkin menyertakan Objek Pekerja di dalam plugin saya, yang akan berisi semua logika dalam dan mentransfer objek Pekerja tersebut ke utas baru? - person Pherrymason; 20.07.2011
comment
@clinisbut ›Bisakah saya memindahkan widget ke thread GUI di onRequestInstallSubwindow() dengan lebih baik? - Tidak, Anda tidak bisa, operasi itu harus dilakukan di thread tempat Anda membuat objek. - person Raiv; 20.07.2011
comment
@clinistapi ya. Ide dengan objek pekerja bagus, Anda dapat melakukan ini. - person Raiv; 20.07.2011