qt的线程使用方法有把某个对象的函数放置线程里执行,方法为moveToThread()

具体操作步骤为:
1、创建一个新的类,让这个类从 QObject 派生

class MyWork:public QObject
{.......
}

2、在这个类中添加一个公共的成员函数,函数体就是我们要子线程中执行的业务逻辑

class MyWork:public QObject
{public:.......// 函数名自己指定, 叫什么都可以, 参数可以根据实际需求添加void working();
}

3、在主线程中创建一个 QThread 对象,这就是子线程的对象

QThread* sub = new QThread;

4、在主线程中创建工作的类对象(千万不要指定给创建的对象指定父对象)

MyWork* work = new MyWork(this);    // error
MyWork* work = new MyWork;          // ok

5、将 MyWork 对象移动到创建的子线程对象中,需要调用 QObject 类提供的 moveToThread() 方法

// void QObject::moveToThread(QThread *targetThread);
// 如果给work指定了父对象, 这个函数调用就失败了
// 提示: QObject::moveToThread: Cannot move objects with a parent
work->moveToThread(sub); // 移动到子线程中工作

6、启动子线程,调用 start(), 这时候线程启动了,但是移动到线程中的对象并没有工作
7、信号槽调用 MyWork 类对象的工作函数,让这个函数开始执行,这时候是在移动到的那个子线程中运行的,需要外面的信号传来让MyWork执行工作函数。

下面是一套完整的工程:

//mywork.h
#ifndef MYWORK_H
#define MYWORK_H#include <QObject>class MyWork : public QObject
{Q_OBJECT
public:explicit MyWork(QObject *parent = nullptr);// 工作函数void working();signals:void curNumber(int num);public slots:
};#endif // MYWORK_H
//mywork.cpp
#include "mywork.h"
#include <QDebug>
#include <QThread>MyWork::MyWork(QObject *parent) : QObject(parent)
{}void MyWork::working()
{qDebug() << "当前线程对象的地址: " << QThread::currentThread();int num = 0;while(1){emit curNumber(num++);if(num == 1000){break;}QThread::usleep(1);}qDebug() << "run() 执行完毕, 子线程退出...";}
//widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include<QString>
#include<QThread>
#include "mywork.h"QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pbStart_clicked();void setNum(int num);private:Ui::Widget *ui;MyWork *work;QThread* sub;
};
#endif // WIDGET_H
//widget.cpp
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 创建线程对象sub = new QThread;// 创建工作的类对象// 千万不要指定给创建的对象指定父对象// 如果指定了: QObject::moveToThread: Cannot move objects with a parentwork = new MyWork;// 将工作的类对象移动到创建的子线程对象中work->moveToThread(sub);// 启动线程sub->start();// 让工作的对象开始工作, 点击开始按钮, 开始工作connect(ui->pbStart, &QPushButton::clicked, work, &MyWork::working);// 显示数据connect(work, &MyWork::curNumber, this, &Widget::setNum);}Widget::~Widget()
{delete ui;
}void Widget::on_pbStart_clicked()
{//    work->working();  //这个有点坑,下面重点讲!
}void Widget::setNum(int num)
{ui->lb_time->setText(QString::number(num));
}

重点来了! 最主要的问题就是子对象的working()函数到底由谁来触发的问题
对比原因在注释写的很清楚了

//正解,主线程点击按钮只是触发信号,而working是由work自己来触发的,并且在子线程执行
connect(ui->pbStart, &QPushButton::clicked, work, &MyWork::working);
//错误示范❌,原因在于下面两个都是指定working由主线程来触发,本质是执行主线程的槽函数
void Widget::on_pbStart_clicked()  //本质上这是个槽函数,点击按钮就执行这个槽函数
{work->working();  //因为work对象在主线程里定义的,如此执行working也是在主线程
}
//或者
connect(ui->pbStart,&QPushButton::clicked,[=](){work->working();  //这和上面on_pbStart_clicked()里被调用没有区别
});

QT线程之 moveToThread() 只能用信号槽方式触发相关推荐

  1. 【QT开发笔记-基础篇】| 第一章 QT入门 | 1.7 如何连接信号槽

    本节对应的视频讲解:B_站_链_接 https://www.bilibili.com/video/BV1mN4y137H6 信号和槽要建立连接,本质上是通过 `connect` 函数来连接实现的. 但 ...

  2. Qt线程之QRunnable的使用详解

    概述 说到线程通常会想到QThread,但其实Qt中创建线程的方式有多种,这里主要介绍其中一种QRunnable,QRunnable和QThread用法有些不同,并且使用场景也有区别.接下来就来看看Q ...

  3. 安全云盘项目(三):3.1 Qt的工具_MVD架构和信号槽原理分析

    一:关于Qt程序整体内容: 二:项目结构模式 (1)MVC:这个已经优点过时,现在前端界面开发最常用的事第二种方式MVD (2)MVD 代码如下: main.cpp #include "xd ...

  4. QT中connect、disconnect和信号槽实现原理

    connect connect用于连接信号和槽函数,但是我们经常忽略最后一个参数,本人在写代码时遇到了bug,选择一个符号进行多次标绘,再选择其他符号时,会将上一次选择的符号也进行标绘,主要时conn ...

  5. 在Qt中使用回调函数替代信号槽

    前言 在Qt中传数据,我们使用了一个信号和槽系统,但这并不意味着不能使用旧的经过验证的方法,即使用 CallBack回调函数功能. 事实上使用 CallBack 功能比信号和槽要快一些.并且当发送信号 ...

  6. Qt信号阻塞和断开信号槽

    Qt信号阻塞和断开信号槽 Qt程序中有时候不希望信号槽的触发,在某段流程结束之后,又需要继续回复信号槽状态,这时候可以用阻塞或者断开信号槽的方法来处理. 1. 阻塞方法 bool QObject::b ...

  7. 13.QT信号槽的连接方式

    QT的信号槽机制和线程的启动方式已经在前面的文章中写过了,本文主要是对信号槽的连接方式进行解读,信号槽的连接方式一共有5种: 1.Qt::DirectConnection 发出信号后立即调用槽函数. ...

  8. Qt学习笔记-----信号槽

    Qt提供signals and slots mechanism(信号槽机制)来保证两个对象之前的关联(connection). 所谓信号槽,简单理解就是两部分,一个是某对象发出的信号,一个是某对象接收 ...

  9. Qt学习之路(9):深入了解信号槽

    信号槽机制是Qt编程的基础.通过信号槽,能够使Qt各组件在不知道对方的情形下能够相互通讯.这就将类之间的关系做了最大程度的解耦. 槽函数和普通的C++成员函数没有很大的区别.它们也可以使virtual ...

最新文章

  1. 安装部署中的数据库打包和快捷方式启动浏览器
  2. 计划策略-10-净需求计划
  3. Python学习笔记:Day13 提升开发效率
  4. Java-二分查找算法
  5. SQL注入(SQL注入(SQLi)攻击)攻击-联合注入
  6. 易度甘特图的功能介绍和开发手册
  7. 【学习笔记】【C语言】结构体
  8. 清华学霸被Facebook开除了
  9. php 截取www后面的目录,php-如何从字符串路径中获取最后一个目录
  10. ubuntu下安装最新 版jre 7
  11. Idea中找不到Java Application 的xml配置文件问题研究
  12. 不加群就可以提取QQ群成员
  13. 震惊!!【微信拼图红包】继微信语音红包后又一新技能
  14. 在线画图工具ProcessOn
  15. 电力拖动自动控制系统_专插本专业全面分析:电子工程及其自动化
  16. 【高效学数据库】第一范式、第二范式、BCNF范式、第三范式、第四范式概念及举例
  17. 统计学 参数估计 之 总体均值的估计
  18. 十二载征程犹未止,看今朝星光尽闪耀丨万字长文回顾2023数据技术嘉年华
  19. bboss ioc快速入门教程
  20. 延边大学计算机专业考研,计算机专业考研成功经验谈

热门文章

  1. 第三方支付机构是如何产生的?有着怎样的历史背景?它的未来又该如何去走得更加辉煌?
  2. 第十二届蓝桥杯省赛JAVA B组杨辉三角形个人题解
  3. [JavaScript] JS求闭区间[min,max]的和
  4. IP归属地查询(基于本地IP库实现)
  5. linux d14 Apache、 Vsftpd
  6. 按键精灵移动端系列 - IOS(苹果版)安装1.3.8 deb
  7. php实现独立模块,poscms独立模块URL规则
  8. 让图片动起来——Real_Time_Image_Animation
  9. Singularity 快速上手, 带你飞
  10. 解决缺少 SHA256.h文件