QPluginLoader ย้ายไปที่เธรด

ฉันกำลังสร้างแอปพลิเคชันที่ต้องอาศัยปลั๊กอินอย่างมาก โดยแกนหลักจะรับข้อมูลจากอินเทอร์เฟซแบบอนุกรมและส่งไปยังปลั๊กอินแต่ละตัว เพื่อให้แต่ละคนตัดสินใจได้ว่าจะทำอย่างไรกับปลั๊กอินนั้น

การออกแบบของฉันอนุญาตให้ปลั๊กอินสร้างวิดเจ็ตที่แนบมากับ MDIArea ผ่าน QMdiSubWindow สิ่งนี้ใช้ได้จนกระทั่งฉันต้องการ mutexes เนื่องจากทุกอย่างทำงานในเธรดเดียวกัน ฉันจึงเกิดการหยุดชะงักอย่างรวดเร็ว ดังนั้นฉันคิดว่าการย้ายปลั๊กอินแต่ละตัวไปยังเธรดอื่นสามารถแก้ปัญหานี้ได้ ปัญหาคือ (ในตอนนี้) 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 );
}

person Pherrymason    schedule 20.07.2011    source แหล่งที่มา


คำตอบ (1)


วิดเจ็ต Qt ทำงานเฉพาะในเธรด GUI เท่านั้น คุณอาจลองย้ายการดำเนินการภายในของปลั๊กอินไปยังเธรดอื่น แต่ GUI ทั้งหมดจะต้องยังคงอยู่ในเธรดหลักของคุณ

ลองสิ่งนี้:

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

แต่ฉันไม่ได้ทดสอบมันอาจจะไม่ทำงาน นอกจากนี้ โปรดจำไว้ว่าการสื่อสารทั้งหมดระหว่างตรรกะภายในของคุณและ gui ควรเป็นแบบปลอดภัยสำหรับเธรดหากโซลูชันของฉันใช้งานได้

person Raiv    schedule 20.07.2011
comment
ฉันสามารถย้ายวิดเจ็ตไปที่เธรด GUI ใน onRequestInstallSubwindow() ดีกว่าได้ไหม - person Pherrymason; 20.07.2011
comment
คำถามคือ: เนื่องจากวิดเจ็ตต้องอยู่ในเธรดหลัก คุณค่าในการสร้างวิดเจ็ตแยกกันในเธรดแยกคืออะไร? สำหรับฉัน ดูเหมือนว่ามันจะเป็นการดีกว่าถ้าย้ายข้อมูลที่อ่านไปยังเธรดอื่น และเก็บการดำเนินการ GUI ทั้งหมดของคุณไว้ที่เธรดหลัก - person Dan Milburn; 20.07.2011
comment
ฉันจะแยกปลั๊กอินออกเป็นสองส่วนได้อย่างไร อาจรวมวัตถุผู้ปฏิบัติงานไว้ในปลั๊กอินของฉัน ซึ่งจะมีตรรกะภายในทั้งหมดและถ่ายโอนวัตถุผู้ปฏิบัติงานนั้นไปยังเธรดใหม่ - person Pherrymason; 20.07.2011
comment
@clinisbut ›ฉันสามารถย้ายวิดเจ็ตไปที่เธรด GUI ใน onRequestInstallSubwindow() ดีกว่าได้ไหม - ไม่ คุณไม่สามารถทำได้ การดำเนินการนั้นจะต้องดำเนินการในเธรดที่คุณสร้างอ็อบเจ็กต์ของคุณ - person Raiv; 20.07.2011
comment
@clinisแต่ใช่ แนวคิดเกี่ยวกับวัตถุผู้ปฏิบัติงานเป็นสิ่งที่ดี คุณสามารถทำได้ - person Raiv; 20.07.2011