2017-07-18 60 views
0

我使用C++ 11 std ::线程来发出请求和响应,然后用响应更新QT lineedit。 我读过从非gui线程更新QT小部件是非法的。 在一些代码,它只是正常工作。 所以我不得不认为QThread无法更新QT小部件,并且C++ 11线程也可以。更新C++ 11线程中的QT小部件

void MyWidget::on_button_clicked() { 
    std::thread([this] { 
     auto req = doSomeRequest(); 
     req.Wait(); 
     auto res = req.response(); 

     ui->lineedit->setText(res.name()); 
     // emit updateName(res.name()); 
    }).detach(); 
} 

但另一种情况,它给了我一个段错误。 有没有人知道QT里面发生了什么?

 
PC: @  0x7f48d426bcda QFontEngineFT::loadGlyphSet() 
*** SIGSEGV (@0x10) received by PID 5484 (TID 0x7f48e4f39780) from PID 16; stack trace: *** 
    @  0x7f48dfde9390 (unknown) 
    @  0x7f48d426bcda QFontEngineFT::loadGlyphSet() 
    @  0x7f48d426bd39 QFontEngineFT::loadGlyphFor() 
    @  0x7f48d426d2cf QFontEngineFT::lockedAlphaMapForGlyph() 
    @  0x7f48e0a721a0 QRasterPaintEngine::drawCachedGlyphs() 
    @  0x7f48e0a74a07 QRasterPaintEngine::drawTextItem() 
    @  0x7f48e0a90905 (unknown) 
    @  0x7f48e091e988 QTextLine::draw() 
    @  0x7f48e091f79d QTextLayout::draw() 
    @  0x7f48e11ce733 QWidgetLineControl::draw() 
    @  0x7f48e1142e2b QLineEdit::paintEvent() 
    @  0x7f48e1051b78 QWidget::event() 
    @  0x7f48e11476f5 QLineEdit::event() 
    @  0x7f48e100c52c QApplicationPrivate::notify_helper() 
    @  0x7f48e1013220 QApplication::notify() 
    @  0x7f48e0266ae0 QCoreApplication::notifyInternal2() 
    @  0x7f48e104a54a QWidgetPrivate::sendPaintEvent() 
    @  0x7f48e104ab5f QWidgetPrivate::drawWidget() 
    @  0x7f48e104b8c4 QWidgetPrivate::paintSiblingsRecursive() 
    @  0x7f48e104b71a QWidgetPrivate::paintSiblingsRecursive() 
    @  0x7f48e104b71a QWidgetPrivate::paintSiblingsRecursive() 
    @  0x7f48e104b71a QWidgetPrivate::paintSiblingsRecursive() 
    @  0x7f48e104a702 QWidgetPrivate::drawWidget() 
    @  0x7f48e104b8c4 QWidgetPrivate::paintSiblingsRecursive() 
    @  0x7f48e104a702 QWidgetPrivate::drawWidget() 
    @  0x7f48e104b8c4 QWidgetPrivate::paintSiblingsRecursive() 
    @  0x7f48e104a702 QWidgetPrivate::drawWidget() 
    @  0x7f48e101b891 (unknown) 
    @  0x7f48e101baf1 (unknown) 
    @  0x7f48e103ba7f QWidgetPrivate::syncBackingStore() 
    @  0x7f48e1051c40 QWidget::event() 
    @  0x7f48e100c52c QApplicationPrivate::notify_helper() 
fish: “./aidmat ../aidmat.ini” terminated by signal SIGSEGV (Address boundary error) 

回答

0

从除主线程以外的任何线程更新QWidgets是非法的。它使用C++ 11线程工作的事实并不合法。

请尝试以下之一:

QMetaObject::invokeMethod(ui->lineedit, "setText", Q_ARG(QString, res.name()); 
// OR 
QString name = res.name(); 
QTimer::singleShot(0, ui->lineedit, [name, this](){ui->lineedit->setText(name);}); 
1

你要做的就是不确定的行为由于Qt的实施。实施和行为因平台而异。 std :: thread类只是系统功能的一个包装。 QThread和类之间的关联是Qt体系结构的一部分,关于哪个标准库没有什么可做,所以通过使用std :: thread,你只是欺骗做Qt库的开发人员告诉你不应该这样做。

如果你需要做你正在尝试的,你应该使用信号插槽系统。