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

QT多线程项目中子线程无法修改主线程的ui组件

情况描述

今天我创建了一个QT多线程的工程,框架如下。我希望通过指针的方式,让子线程去直接修改主线程的ui组件,但事与愿违。

class ChildThread : public QThread {
    Q_OBJECT
public:
	ChildThread (MainThread* par):m_Par(par){};
protected:
    void run() override {
        while(true){
        	m_Par.ui->label.setValue()//子线程修改主线程的ui组件
        }
    }
public:
	MainThread* m_Par
};

class MainThread : public QWidget {
    Q_OBJECT
public:
    MainThread (QWidget *parent = nullptr) : QWidget (parent) {
        QLabel *label = new QLabel("Current Time: ", this);
        setCentralWidget(label);
        // 创建子线程
        m_ChildThread= new ChildThread (this);
        // 启动子线程
        m_ChildThread->start();
    }
private:
    ChildThread *m_ChildThread;
};

存在的问题:子线程修改主线程ui是不安全操作

在Qt中,GUI相关的操作(例如更新UI元素)通常应该在主线程中执行。直接在子线程中更新UI是不安全的,可能会导致未定义的行为或崩溃。
正确的做法是:利用QT的信号与槽函数机制。在子线程处理完业务后,发出信号并携带上结果给主线程,交给主线程渲染。

class ChildThread : public QThread {
    Q_OBJECT
signals:
    void Msg(const QString& message);
public:
	ChildThread ();
protected:
    void run() override {
        while(true){
        	emit Msg("这是一条消息");
        }
    }
public:
	MainThread* m_Par
};

class MainThread : public QWidget {
    Q_OBJECT
public:
    MainThread (QWidget *parent = nullptr) : QWidget (parent) {
        QLabel *label = new QLabel("Current Time: ", this);
        setCentralWidget(label);
        // 创建子线程
        m_ChildThread= new ChildThread ();
        connect(m_ChildThread, &m_ChildThread::Msg, this, &MainThread::Msg);
        // 启动子线程
        m_ChildThread->start();
    }
private slots:
	void Msg(const QString& message){ this.label.setText(message); }
private:
    ChildThread *m_ChildThread;
};

这里要注意两点:
1、信号携带的数据要和槽函数接受的数据保持一致,变量名可以不一样。

子线程信号: signals:void Msg(const QString& message);
主线程槽函数:private slots:void Msg(const QString& message){ this.label.setText(message); }

2、信号与槽函数链接,如果官方的链接方式无效果,就换成直接引用。

方式一 connect(m_ChildThread, SINGAL(m_ChildThread::Msg), this, SLOT(&MainThread::Msg));
方式二 connect(m_ChildThread, &m_ChildThread::Msg, this, &MainThread::Msg);


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

相关文章:

  • Molecular signatures database (MSigDB) 3.0
  • 给阿里云OSS绑定域名并启用SSL
  • 深入探索 TypeScript:从基础到高级特性
  • 从H264视频中获取宽、高、帧率、比特率等属性信息
  • RabbitMQ 篇-深入了解延迟消息、MQ 可靠性(生产者可靠性、MQ 可靠性、消费者可靠性)
  • 在esxi8.0中安装黑群晖的过程记录及小问题处理
  • Windows 下 Sublime Text 3.2.2 下载及配置
  • Object常用方法——toString()
  • Linux - 进一步理解 文件系统 - inode - 机械硬盘
  • C语言程序设计(入门)
  • py 字符串转INT
  • PS 颜色取样器标尺工具 基本使用讲解
  • Linux中的进程终止(详解)
  • Pandas数据操作_Python数据分析与可视化
  • Python学习(一)基础语法
  • 11. Spring源码篇之实例化前的后置处理器
  • ElasticSearch综合练习题,ES为8版本,使用Kibana运行语句
  • SQL Server中substring的用法
  • 在Rust编程中使用泛型
  • Mysql-CRUD(增删查改)
  • PS学习笔记——新建文档/修改文档
  • 【飞控调试】DJIF450机架+Pixhawk6c mini+v1.13.3固件+好盈Platinium 40A电调无人机调试
  • 竞赛选题 深度学习验证码识别 - 机器视觉 python opencv
  • 工厂自动化中DCS软件
  • 让你彻底学会HBase
  • 11.5MyBatis(进阶)