Qt中弹出错误:ASSERT: qApp && App->thread() == QThread::currentThread()

本文解释了Qt中GUI类如QWidget及其子类并非线程安全的特性,它们只能从主线程进行操作。若要在子线程中修改UI,可以通过信号或事件机制通知主线程来完成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原因

Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread.

 

子线程中读取Qt的UI属性可以,修改不可以!

可在子线程中使用信号或事件传给主线程去修改Qt的UI

 

原始链接

http://www.qtcn.org/bbs/simple/?t26899.html

tryQtWidgetsApp::tryQtWidgetsApp(QWidget* parent) : QMainWindow(parent) { ui.setupUi(this); //这里也可以修改为自适应 ui.groupBox_8->move(10, 10); //从ini读取设置信息 QSettings settings("config.ini", QSettings::IniFormat); //读取串口号 QString serialName = settings.value("Option/serialNumber").toString(); int serialName_i = serialName.toInt(); //将spinbox显示为默认输入的值 ui.spinBox->setValue(serialName_i); //读取波特率 QString baudRate = settings.value("Option/baudRate").toString(); DWORD baudRate_i = baudRate.toInt(); ui.comboBox->setCurrentText(baudRate); //将串口号应用到serialReader线程中 std::wstringstream ss; // 用流实现拼接 ss << TEXT("\\\\.\\COM") << settings.value("Option/serialNumber").toInt(); std::wstring portName = ss.str(); LPCWSTR COM_PORT = portName.c_str(); //const LPCWSTR COM_PORT = TEXT("\\\\.\\COM8"); const QString COM_PORT_QS = QString::fromStdWString(COM_PORT); //SerialReader* serialReader = new SerialReader("COM8", this); SerialReader* serialReader = new SerialReader(COM_PORT_QS, baudRate_i, this); DataMonitor* dataMonitor = new DataMonitor(serialReader); // 连接 SerialReader 的错误信号到主窗口的 showError 槽 connect(serialReader, &SerialReader::errorOccurred, this, &tryQtWidgetsApp::showError); // 启动串口读取线程 serialReader->start(); //链接 connect(dataMonitor, &DataMonitor::dataUpdated, this, &tryQtWidgetsApp::setLabel); QObject::connect(ui.pushButton_2, &QPushButton::clicked, this, [&]() { //ok按钮按下时候要写入一下设置的值 QSettings settings("config.ini", QSettings::IniFormat); //写入串口号 settings.setValue("Option/serialNumber", ui.spinBox->value()); //写入波特率 settings.setValue("Option/baudRate", ui.comboBox->currentText()); QMessageBox msgBox; msgBox.setIcon(QMessageBox::Question); msgBox.setWindowTitle("注意"); msgBox.setText("设置已保存,是否重启并应用?"); // 添加两个标准按钮 QPushButton* confirmBtn = msgBox.addButton(QMessageBox::Ok); // "确定"按钮 QPushButton* cancelBtn = msgBox.addButton(QMessageBox::Cancel); // "取消"按钮 msgBox.resize(400, 200); msgBox.setStyleSheet("QMessageBox { font-size: 16px; }"); // 执行对话框并获取点击结果 int ret = msgBox.exec(); //printf("1"); // 判断用户点击了哪个按钮 if (ret == QMessageBox::Ok) { serialReader->requestInterruption(); // 请求中断 serialReader->wait(); // 等待线程退出 qApp->quit(); QProcess::startDetached(qApp->applicationFilePath(), QStringList()); } else if (ret == QMessageBox::Cancel) { //this->close(); } }); }为什么请求中断的时候会抛出异常
03-11
connect(this, &ML_WaferManage::Sig_dispenserWorkDone, this, [=](const auto& _errorString) { if (ML_GemManager::getInstance()->isOnline() && ML_GemManager::getInstance()->isRemoteControl()) { emit ML_GemManager::getInstance()->SIG_notifyEvent(MS_EVENT::MS_EVENT_SWFinisheDisp); MS_GemGetAttrData aa; emit ML_GemManager::getInstance()->SIG_notifyStripMapStruct(aa); } if (_errorString.isEmpty()) { m_workFinished = true; emit Sig_dispenserWorSuccess(); //add ly m_WaferTimer->stop(); //点胶完成,停止计时 } else { MA_Auxiliary::promptMessageBoxWithButton(QMessageBox::Warning, tr("警告"), tr("点胶流程执行失败,是否执行送出wafer?"), { { MA_Auxiliary::createPushButton(tr("送出")), QMessageBox::Yes }, { MA_Auxiliary::createPushButton(tr("停止")), QMessageBox::No, } }, [=](auto _buttonClicked, auto _messsageBox) { Q_ASSERT(_messsageBox); _messsageBox->close(); if (_messsageBox->getButtonIndex(_buttonClicked) == QMessageBox::Yes) { m_workFinished = true; emit Sig_dispenserWorSuccess(); dataBaseLog::messageLog(ML_Logger_MS::MS_Loginfo{ ML_Logger_MS::ME_LogLevel::LV_INFO, logAuxiliary::getModule(c_LoggerModule_WorkInfo), logAuxiliary::getModule(c_LoggerKeyword_Work), tr("自动流程:点胶流程执行失败,操作员选择送出wafer"), LOG_Debug }); return; } else { m_workFinished = false; dataBaseLog::messageLog(ML_Logger_MS::MS_Loginfo{ ML_Logger_MS::ME_LogLevel::LV_INFO, logAuxiliary::getModule(c_LoggerModule_WorkInfo), logAuxiliary::getModule(c_LoggerKeyword_Work), tr("自动流程:点胶流程执行失败,操作员选择停止流程"), LOG_Debug }); } }, QMessageBox::Cancel); } }); }
03-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值