首页 > 其他分享 >简单例子理解 Qt 中 QObject: Cannot create children for a parent that is in a different thread. 问题

简单例子理解 Qt 中 QObject: Cannot create children for a parent that is in a different thread. 问题

时间:2023-11-16 10:00:27浏览次数:33  
标签:parent different Qt thread ThreadTest2 QObject 线程 include QThread

c++ gui programming with qt 中关于 QThread的用法的限制
下面这句话的翻译不清
QObject is reentrant, but there are three constraints to keep in mind:

Child QObjects must be created in their parent's thread.
In particular, this means that the objects created in a secondary thread must never be created with the QThread object as their parent, because that object was created in another thread (either the main thread or a different secondary thread).

中文翻译为 QObject 的子对象必须在他的父对象线程中创建 。应改为“QObject 的子对象必须在他的父对象所在的线程中创建”
就好理解了。
因为QThread 对象声明时是 在主线程或 其他线程中,在Qthread对象中声明的对象以该Qthread为父亲的对象和该QThread的对象不在同一线程。

实例:
#ifndef THREADTEST2_H
#define THREADTEST2_H
#include
#include

class Class1 : public QObject
{
public:
Class1(QObject* parent) : QObject(parent){}
};

class ThreadTest2 : public QThread
{
public:
ThreadTest2()
{
qDebug() << "ThreadTest2::ThreadTest2, thread = " << QThread::currentThread();
}

void run() override

{

qDebug() << "ThreadTest2::run, thread = " << QThread::currentThread();//**

qDebug() << "ThreadTest2::run, ThreadTest2 thread = " << this->thread();//**

m_class = new Class1(this);//父对象

}

private:
Class1* m_class = nullptr;
};

#endif // THREADTEST2_H

#include
#include "qthreadtest.h"
#include "threadtest2.h"
#include

int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);

ThreadTest2 thread2;
thread2.start();

return app.exec();

}


编译结果
ThreadTest2::ThreadTest2, thread = QThread(0x2864244cbd0)
ThreadTest2::run, thread = QThread(0x8d9d4ff7a8)
ThreadTest2::run, ThreadTest2 thread = QThread(0x2864244cbd0)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QThread(0x8d9d4ff7a8), parent's thread is QThread(0x2864244cbd0), current thread is QThread(0x8d9d4ff7a8)
————————————————
由运行结果看出 thread2(ThreadTest2)属于主线程(QThread(0x2864244cbd0)),我们尝试在 QThread(0x2864244cbd0)线程中为属于(QThread(0x2864244cbd0))的 thread2 对象创建子对象,所以出问题了。

————————————————

解决方法

那么我们可以如何避免出现这种问题呢,方法有很多种,下面介绍几种:

1. 创建对象时不指定父对象

既然问题出在为父对象创建子对象过程中,那么我们创建对象时不指定父对象不就好了,修改如下:
#ifndef THREADTEST2_H
#define THREADTEST2_H
#include
#include

class Class1 : public QObject
{
public:
Class1(QObject* parent = nullptr) : QObject(parent){}
};

class ThreadTest2 : public QThread
{
public:
ThreadTest2()
{
qDebug() << "ThreadTest2::ThreadTest2, thread = " << QThread::currentThread();
}

void run() override
{
    qDebug() << "ThreadTest2::run, thread = " << QThread::currentThread();
    qDebug() << "ThreadTest2::run, ThreadTest2 thread = " << this->thread();
    m_class = new Class1();
}

private:
Class1* m_class = nullptr;
};

#endif // THREADTEST2_H
显然这种方式不是很好,不指定父对象,创建的m_class对象的释放就要由自己管理了。我们可以看看其他方法。

2. 使用moveToThread设置对象绑定的线程

既然是因为在不同的线程创建子对象出问题了,那么我们将父对象属于的线程与执行线程设置为同一个线程不就好了吗。修改如下
#include
#include "qthreadtest.h"
#include "threadtest2.h"
#include

int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);

ThreadTest2 thread2;
thread2.moveToThread(&thread2);
thread2.start();

return app.exec();

}
运行结果
ThreadTest2::ThreadTest2, thread = QThread(0x20f230c0d80)
ThreadTest2::run, thread = QThread(0xb5db97fb58)
ThreadTest2::run, ThreadTest2 thread = QThread(0xb5db97fb58)
可以看到thread2绑定的线程变为QThread(0xb5db97fb58),与run执行线程属于同一个线程了。

3. 将子对象的创建放到启动执行线程的线程中完成

既然是因为在不同的线程创建子对象出问题了,我们可以将子对象的创建放到父对象绑定的线程中创建就好了,就上面例子而言简单的方法就是将子对象的创建放到父对象的构造函数中
#ifndef THREADTEST2_H
#define THREADTEST2_H
#include
#include

class Class1 : public QObject
{
public:
Class1(QObject* parent = nullptr) : QObject(parent){}
};

class ThreadTest2 : public QThread
{
public:
ThreadTest2()
{
m_class = new Class1(this);
qDebug() << "ThreadTest2::ThreadTest2, thread = " << QThread::currentThread();
}

void run() override
{
    qDebug() << "ThreadTest2::run, thread = " << QThread::currentThread();
    qDebug() << "ThreadTest2::run, ThreadTest2 thread = " << this->thread();
}

private:
Class1* m_class = nullptr;
};

#endif // THREADTEST2_H

版权声明:本文为CSDN博主「-Davis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_35511927/article/details/121422908

标签:parent,different,Qt,thread,ThreadTest2,QObject,线程,include,QThread
From: https://www.cnblogs.com/keleman/p/17835539.html

相关文章

  • 第7章 Qt 窗口--开发云对象存储浏览器的登录窗口
    Qt窗口--开发云对象存储浏览器的登录窗口本章导学学习常用的控件,通过文档使用控件窗口基本知识讲解(代码7-2)生活中的窗口是连接人与外面风景的桥梁,计算机的窗口是连接人和操作系统资源的桥梁,并且更加方便,使用命令行太难了任务栏的应用程序上一般为顶层窗口,顶层窗......
  • 第8章 Qt 布局管理--动态调整浏览器登录
    Qt布局管理--动态调整浏览器登录控件没有跟随窗口变大的位置布局管理器概念及原理讲解参考值:控件变化的最小限度扩展策略:水平垂直扩展时扩展的方案都拉伸还是只拉伸,还有保持不变的方案比利:多个控件分别按多少比利1:1间隙:美观边距:美观这块吃实践,暂时放着··......
  • 第6章 Qt GUI--界面编程基础
    QtGUI--界面编程基础认识设计师界面--每个窗口的功能及用法在UI设计师界面设计的属性会被QTwidget设计在这里面拖动拖放试试看属性是根据基础的父类从上到下排序的编辑和信号槽模式核心--信号槽的理解与应用(这里比较粗糙)QT和其他GUI框架最大的区别红灯是......
  • vs 2019安装QT
    vs2019安装QTvs2019安装页面QT安装页面QT下载项QT(在线安装程序):QT的OnlineInstaller(在线安装程序)是Qt官方提供的一种下载和安装Qt开发工具包的方法。与传统的离线安装程序不同,OnlineInstaller是一个小型的安装程序,它将下载和安装Qt的组件时仅下载所需的文件,而不是整......
  • 软件设计开发笔记5:QT开发三参数温室气体数据记录软件
      最近有一个为三参数温室气体分析仪及其多通道换向阀箱编写数据记录和控制的需求。所以在这一篇中我们就来分析一下如何使用QT实现这一需求。1、需求分析  虽然说传递过来的需求只有“实现一个三参数温室气体分析仪及其多通道换向阀箱的数据记录和控制”这样一句话,但所有人都......
  • QT环境变量
    exportQT_DIR=/userdata/bin/qtlibexportQT_QPA_PLATFORM=eglfsexportQT_QPA_EGLFS_INTEGRATION=eglfs_kmsexportQT_QPA_EGLFS_KMS_PLANE_INDEX=1exportQT_QPA_EGLFS_ALWAYS_SET_MODE=1exportQT_QPA_EGLFS_NO_LIBINPUT=1exportQT_LOGGING_RULES='qt.qpa.*=false&#......
  • 本地MQTT协议消息服务远程连接教程介绍
    Mosquitto是一个开源的消息代理,它实现了MQTT协议版本3.1和3.1.1。它可以在不同的平台上运行,包括Windows、Linux、macOS等。mosquitto可以用于物联网、传感器、移动应用程序等场景,提供了一种轻量级的、可靠的、基于发布/订阅模式的消息传递机制。MQTT协议远程访问的好处在于它可以......
  • Qt 如何配置CLion标准控制台输出?
    CMake相关问题:即CMakeLists.txt文件中,在add_executable添加了WIN32。即当使用了WIN32标识后,就去掉了控制台,那么自然就没有信息打印出来了。#forexampleadd_executable(${PROJECT_NAME}WIN32${_SRC_FILES}${_PLATFORM_SRC_FILES}${_UI_FILES}${_RES_FIL......
  • Windows10上安装Mosquitto的步骤(win10、win11 安装mqtt)
    目录· 前言· 1.下载安装· 2.设置Broker的IP和Port· 3.设置账户和密码· 4.重启服务mosquittobroker· 5.如何让Windows服务开机自启前言mosquitto是一款开源免费的软件,官网链接。它是一些可执行文件的集合,通过这些可执行文件,它提供broker,publish,subscribe功能......
  • Vue_MQTT项目搭建记录
    新建vue3项目#新建vite+vue3的项目npminitvue@latestyarn安装依赖包yarnaddmqtt初探-连接阿里云物联网平台代码:<template><div><h1>LED-IOT</h1><button@click="connectToBroker">Connect</button><button@......