在c ++ 11 thread

时间:2017-07-18 04:11:36

标签: multithreading qt c++11

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

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)

2 个答案:

答案 0 :(得分:1)

由于Qt的实施,您所做的是未定义的行为。实施和行为因平台而异。 std :: thread类只是系统功能的包装器。 QThread和类之间的关联是Qt体系结构的一部分,关于哪个标准库无关,所以通过使用std :: thread,你只是作弊去做Qt库的开发人员告诉你不应该这样做。

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

答案 1 :(得分: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);});