当前位置: 首页 > article >正文

Qt之Cannot create children for a parent that is in a different thread问题分析

问题

在多线程场景中,使用QSerialPort,QTcpSocket等QIODevice设备时出现报Cannot create children for a parent that is in a different thread

分析

QObject构造函数中会检查父对象的线程数据与当前对象的线程数据是否一致

static bool check_parent_thread(QObject *parent,
                                QThreadData *parentThreadData,
                                QThreadData *currentThreadData)
{
    if (parent && parentThreadData != currentThreadData) {
        QThread *parentThread = parentThreadData->thread.loadAcquire();
        QThread *currentThread = currentThreadData->thread.loadAcquire();
        qWarning("QObject: Cannot create children for a parent that is in a different thread.\n"
                 "(Parent is %s(%p), parent's thread is %s(%p), current thread is %s(%p)",
                 parent->metaObject()->className(),
                 parent,
                 parentThread ? parentThread->metaObject()->className() : "QThread",
                 parentThread,
                 currentThread ? currentThread->metaObject()->className() : "QThread",
                 currentThread);
        return false;
    }
    return true;
}

在公有构造函数explicit QObject(QObject *parent=nullptr);和保护构造函数QObject(QObjectPrivate &dd, QObject *parent = nullptr)

QObject::QObject(QObject *parent)
    : d_ptr(new QObjectPrivate)
{
    Q_ASSERT_X(this != parent, Q_FUNC_INFO, "Cannot parent a QObject to itself");

    Q_D(QObject);
    d_ptr->q_ptr = this;
    d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
    d->threadData->ref();
    if (parent) {
        QT_TRY {
            if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
                parent = 0;
            setParent(parent);
        } QT_CATCH(...) {
            d->threadData->deref();
            QT_RETHROW;
        }
    }
#if QT_VERSION < 0x60000
    qt_addObject(this);
#endif
    if (Q_UNLIKELY(qtHookData[QHooks::AddQObject]))
        reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this);
    Q_TRACE(QObject_ctor, this);
}

QObject::QObject(QObjectPrivate &dd, QObject *parent)
    : d_ptr(&dd)
{
    Q_ASSERT_X(this != parent, Q_FUNC_INFO, "Cannot parent a QObject to itself");

    Q_D(QObject);
    d_ptr->q_ptr = this;
    d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
    d->threadData->ref();
    if (parent) {
        QT_TRY {
            if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
                parent = 0;
            if (d->isWidget) {
                if (parent) {
                    d->parent = parent;
                    d->parent->d_func()->children.append(this);
                }
                // no events sent here, this is done at the end of the QWidget constructor
            } else {
                setParent(parent);
            }
        } QT_CATCH(...) {
            d->threadData->deref();
            QT_RETHROW;
        }
    }
#if QT_VERSION < 0x60000
    qt_addObject(this);
#endif
    if (Q_UNLIKELY(qtHookData[QHooks::AddQObject]))
        reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this);
    Q_TRACE(QObject_ctor, this);
}

http://www.kler.cn/a/472680.html

相关文章:

  • 2、蓝牙打印机点灯-GPIO输出控制
  • Electron快速入门——跨平台桌面端应用开发框架
  • Boost.Asio 同步读写及客户端 - 服务器实现详解
  • 如何配置Cursor的显示主题模式
  • springboot + vue+elementUI图片上传流程
  • tomcat12启动流程源码分析
  • uniapp的两种弹窗方式
  • ffmpeg aac s16 encode_audio.c
  • idea 编辑竖列:alt +shift+insert
  • Python的Matplotlib库应用(超详细教程)
  • C++ ——— 匿名对象
  • Spring AI零起点搭建AI应用
  • spring:xml声明bean的多种方式。
  • 电脑32位和64位之区别(Difference between 32-Bit and 64 Bit Computers)
  • Python —— 常用的字符串方法
  • STM32-笔记39-SPI-W25Q128
  • python matplotlib.pyplot中绘制带文字标注的箭头,使其指向某一特定数据点
  • 使用SpringBoot-data-mongodb操作MongoDB
  • 总结2024,迎接2025
  • 一套极简易的直流无刷电机(Deng FOC)开发套件介绍
  • 企业开通部署 Azure OpenAI 流程:如何创建一个AI聊天机器人
  • 【深度学习基础】线性神经网络 | 线性回归的简洁实现
  • 单片机死机问题处理
  • (2023|NIPS,LLaVA-Med,生物医学 VLM,GPT-4 生成自指导指令跟随数据集,数据对齐,指令调优)
  • 简易CPU设计入门:算术逻辑单元(一)
  • 技术选型深度解析:Qt、PyQt与Vue在界面开发中的权衡与抉择