【问题标题】:update QT widget in c++11 thread在 c++11 线程中更新 QT 小部件
【发布时间】:2017-07-18 04:11:35
【问题描述】:

我正在使用 c++11 std::thread 发出请求和响应,然后使用响应更新 QT lineedit。 我读过从非 gui 线程更新 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() *** PID 5484 (TID 0x7f48e4f39780) 从 PID 16 接收到 SIGSEGV (@0x10);堆栈跟踪: *** @ 0x7f48dfde9390(未知) @ 0x7f48d426bcda QFontEngineFT::loadGlyphSet() @ 0x7f48d426bd39 QFontEngineFT::loadGlyphFor() @ 0x7f48d426d2cf QFontEngineFT::lockedAlphaMapForGlyph() @ 0x7f48e0a721a0 QRasterPaintEngine::drawCachedGlyphs() @ 0x7f48e0a74a07 QRasterPaintEngine::drawTextItem() @ 0x7f48e0a90905(未知) @ 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(未知) @ 0x7f48e101baf1(未知) @ 0x7f48e103ba7f QWidgetPrivate::syncBackingStore() @ 0x7f48e1051c40 QWidget::event() @ 0x7f48e100c52c QApplicationPrivate::notify_helper() 鱼:“./aidmat ../aidmat.ini”由信号 SIGSEGV 终止(地址边界错误)

【问题讨论】:

    标签: multithreading qt c++11


    【解决方案1】:

    由于 Qt 的实现,您所做的是未定义的行为。实现和行为因平台而异。 std::thread 类只是系统功能的包装。 QThread 和类之间的关联是 Qt 体系结构的一部分,即与哪个标准库无关,因此使用 std::thread 只是欺骗去做 Qt 库的开发人员告诉你不应该做的事情。

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

    【讨论】:

      【解决方案2】:

      从除主线程之外的任何线程更新 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);});
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-08-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-28
        相关资源
        最近更新 更多