Qt 多线程(QThread)

使用Qt中的QThread创建线程 文章目录1. 使用信号和槽的形式触发2. 使用继承自QThread方式触发3. 几点说明 上篇文章中简单介绍了如何使用 Windows API 和c++11中的 std::thread 创建线程。 线程的创建和基本使用 本篇文章将会介绍如何使用QThread创建线程。 QThread是Qt所有线程控制的基础,每一个QThread实例对象控制一个线程。 QThread可以直接实例化使用也可以用... 阅读详情

Qt 多线程(QThread)

一.理解QThread

关于QThread,参考qt助手中的解析

Detailed Description
A QThread object manages one thread of control within the program. QThreads begin executing in run(). By default, run() starts the event loop by calling exec() and runs a Qt event loop inside the thread.
You can use worker objects by moving them to the thread using QObject::moveToThread().
(详细说明
QThread对象管理程序中的一个控制线程。QThreads开始在run()中执行。默认情况下,run()通过调用exec()启动事件循环,并在线程内运行Qt事件循环。
您可以通过使用QObject::moveToThread()将辅助对象移动到线程来使用它们。)

注意:实际上,QThread可以理解为线程控制器,它本身并不是一个线程,只是QThread管理了一个线程而已。
实际上,继承自QThread的类中,下面两种情况的代码才是运行在次线程中。
(1).run()函数的代码。
(2).次线程执行exec()函数,开启事件循环。某个继承自QObject的类obj,通过moveToThread()函数移入次线程,
并且通过信号槽机制触发obj的槽函数(信号槽连接方式不能为 Qt::DirectConnection)

二.QThread的使用方法。

方法1:新建一个类,继承类QThread,重载run()函数,并将关键代码放到run()中执行。执行完成后,发送信号,告诉主线程完成。

//workerthread.h

#ifndef WORKERTHREAD_H
#define WORKERTHREAD_H
#include <QThread>

class WorkerThread : public QThread
{
    Q_OBJECT

public:
    WorkerThread(QObject *parent = nullptr);


protected:
    void run();

signals:
    void sigResult();
};

#endif // WORKERTHREAD_H

//workerthread.cpp

#include "workerthread.h"
#include <QDebug>

WorkerThread::WorkerThread(QObject *parent)
    :QThread(parent)
{

}

void WorkerThread::run()
{
    /*
     死循环,让线程一直跑。或者处理完毕就退出
     */
    qDebug()<<"WorkerThread run: threadId: "<<QThread::currentThreadId();
    emit sigResult();
}

//mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "myThread1.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

private slots:
    void slotResult();
    void slotResultQueued();
    void slotResultDirect();

};
#endif // MAINWINDOW_H

//mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QThread>
#include <QDebug>
#include <workerthread.h>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    qDebug()<<"main threadId: "<<QThread::currentThreadId();
    WorkerThread *workthread = new WorkerThread(this);
    //匿名槽函数,槽函数运行在次线程
    connect(workthread, &WorkerThread::sigResult, [=]()
    {
        qDebug()<<"lanba slot threadId: "<<QThread::currentThreadId();
    });

    //普通连接方式,槽函数运行在主线程
    connect(workthread, &WorkerThread::sigResult, this, &MainWindow::slotResult);

    //队列连接
    connect(workthread, &WorkerThread::sigResult, this, &MainWindow::slotResultQueued, Qt::QueuedConnection);

    //直接连接
    connect(workthread, &WorkerThread::sigResult, this, &MainWindow::slotResultDirect, Qt::DirectConnection);
    workthread->start();
}

MainWindow::~MainWindow()
{
    delete ui;
}

//普通连接方式的槽函数
void MainWindow::slotResult()
{
    qDebug()<<"slotResult threadId: "<<QThread::currentThreadId();
}

//队列连接方式的槽函数
void MainWindow::slotResultQueued()
{
    qDebug()<<"slotResultQueued threadId: "<<QThread::currentThreadId();
}

//直接连接方式的槽函数
void MainWindow::slotResultDirect()
{
    qDebug()<<"slotResultDirect threadId: "<<QThread::currentThreadId();
}

运行结果:
在这里插入图片描述
结论:
使用上述方式调用线程槽函数所在的线程如下:
1.槽函数为匿名函数,槽函数运行在发送者所在的线程。
2.采用Qt::DirectConnection方式连接信号槽,槽函数运行在发送者所在的线程。
3.其它连接方式,槽函数运行在接受者所在的线程。

方法2:次线程在run()函数中执行exec()函数,开启事件循环。某个继承自QObject的类obj,通过moveToThread()函数移入次线程,
并且通过信号槽机制触发obj的槽函数(信号槽连接方式不能为 Qt::DirectConnection)

//workerThread.h

#ifndef WORKERTHREAD_H
#define WORKERTHREAD_H
#include <QThread>

class WorkerThread : public QThread
{
    Q_OBJECT

public:
    WorkerThread(QObject *parent = nullptr);


protected:
    void run();
};

//workerThread.cpp

#include "workerthread.h"
#include <QDebug>

WorkerThread::WorkerThread(QObject *parent)
    :QThread(parent)
{

}

void WorkerThread::run()
{
    qDebug()<<"WorkerThread run: threadId: "<<QThread::currentThreadId();
    exec();		//执行exec()函数,开启事件循环
}

//worker.h

#ifndef WORKER_H
#define WORKER_H

#include <QObject>

class Worker : public QObject
{
    Q_OBJECT

public:
    explicit Worker(QObject *parent = nullptr);


signals:
    void sigFinished();

public slots:
    void doSomething();
};

#endif // WORKER_H

//worker.cpp

#include "worker.h"
#include <QThread>
#include <QDebug>

Worker::Worker(QObject *parent) :
    QObject(parent)
{

}

void Worker::doSomething()
{
    qDebug()<<"worker doSomething: threadId: "<<QThread::currentThreadId();
    emit sigFinished();
}

//mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "myThread1.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

signals:
    void sigDoSomething();

private slots:
    void slotFinished();
    void slotFinishedQueued();
    void slotFinishedDirect();

};
#endif // MAINWINDOW_H

//mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QThread>
#include <QDebug>
#include <workerthread.h>
#include <worker.h>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    qDebug()<<"main threadId: "<<QThread::currentThreadId();
    WorkerThread *workthread = new WorkerThread(this);
    Worker *worker = new Worker();      //不能设置父类
    worker->moveToThread(workthread);   //将worker 移动到 次线程

    //主线程发送信号,次线程接收信号,槽函数运行在接受者线程。
    connect(this, &MainWindow::sigDoSomething, worker, &Worker::doSomething);

    //匿名函数
    connect(worker, &Worker::sigFinished, [=]()
    {
        qDebug()<<"lanba slot threadId: "<<QThread::currentThreadId();
    });

    //普通连接方式,槽函数运行在接受者线程
    connect(worker, &Worker::sigFinished, this, &MainWindow::slotFinished);
    //队列连接,槽函数运行在接受者线程
    connect(worker, &Worker::sigFinished, this, &MainWindow::slotFinishedQueued, Qt::QueuedConnection);
    //直接连接,槽函数运行在发送者所在线程。
    connect(worker, &Worker::sigFinished, this, &MainWindow::slotFinishedDirect, Qt::DirectConnection);

    workthread->start();
    emit sigDoSomething();

}

MainWindow::~MainWindow()
{
    delete ui;
}

//普通连接方式的槽函数
void MainWindow::slotFinished()
{
    qDebug()<<"slotFinished threadId: "<<QThread::currentThreadId();
}

//队列连接方式的槽函数
void MainWindow::slotFinishedQueued()
{
    qDebug()<<"slotFinishedQueued threadId: "<<QThread::currentThreadId();
}

//直接连接方式的槽函数
void MainWindow::slotFinishedDirect()
{
    qDebug()<<"slotFinishedDirect threadId: "<<QThread::currentThreadId();
}

//运行 结果
在这里插入图片描述
结论,通过moveToThread()方式,确实可以将槽函数运行在次线程(信号槽连接方式不能为:Qt::DirectConnection)

QT之多线程(QThread)的简单使用 一、线程简述 线程(thread)是操作系统能够进行运算调度的最小单位。一条线程指的是进程中一个单一顺序的控制流,它被包含在进程之中,是进程中的实际运作单位。一个进程中可以并发多个线程,每条线程并行执行不同的任务。如一边解码一边播放视频,提高了效率,节约了时间。 Qt中通过QThread直接支持多线程,QThread是一个跨平台的多线程解决方案 ,QThread以简洁易用的方式实现多线程编程 二、线程状态 多个线程全部启动(new)进入就绪队列 执行后处于运行状态,不运行就处在阻塞状态 .. 阅读详情

相关推荐

Qt 串口 QThread多线程

Qt串口多线实现

Rough Set 5652

Qt之QThread(深入理解)

简述 为了让程序尽快响应用户操作,在开发应用程序时经常会使用到线程。对于耗时操作如果不使用线程,UI界面将会长时间处于停滞状态,这种情况是用户非常不愿意看到的,我们可以用线程来解决这个问题。 前面,已经介绍了QThread常用的两种方式: Worker-Object 子类化QThread 下面,我们来看看子类化QThread在日常中的应用。 简述 子类化QThread 线程休眠...

希望能帮助大家,希望大家多多支持,你们的支持是我前进的动力。 1万+

一文搞定之Qt多线程(QThread、moveToThread)

总结在Qt中如何实现多线程编程。

树欲静静风不止止的博客 4万+

Qt线程QThread详解

在程序中使用线程可以提高程序的性能、并发性、响应性和稳定性,使得程序设计更加灵活和简单。但是,线程编程也有一些挑战,如线程安全性和死锁等问题需要格外注意。我们使用QT框架编程时,可以用框架提供的线程类QThread来管理线程。本文将介绍使用QThread编程时的两种方式,并给出一个数据同步的示例。在介绍QThread之前先复习下线程的定义,线程是操作系统中的基本执行单元,是一个独立的执行路径。每个线程都有自己的栈空间,用于存储本地变量和函数调用的上下文。

北极星的技术笔记 1万+

QT多线程的实现方式:QThread run优雅的创建与退出【QT多线程】

QThread 是用来管理线程的,它所依附的线程和它管理的新线程并不是同一个东西QThread 所依附的线程,就是执行创建QThread的线程。也就是咱们这儿的主线程,QThread 管理的新线程,就是 run 启动的线程。所以总结一句话:QThread只有run函数是在新线程里的,其他所有函数都在QThread生成的线程里那么就抛出两个问题1.QThread的对象依附在主线程中,次线程的slot函数会在主线程中执行,而不是次线程。除非:(不建议这样做)

吻等离子的博客 1万+

Qt基础-QThread多线程详解

本文详解Qt的QThread多线程,实例演示两种使用方式。

qq_30725967的博客 1122

【QT】一文学会 QT 多线程(QThread )

多线程是提高应用程序性能和响应速度的常用技术之一,而在 Qt 中实现多线程也变得异常简单和高效。本文将对 Qt 中实现多线程的几种常用方法进行介绍,并结合示例程序展示其实际应用。

island1314的博客 8493

使用STM32F103C8T6控制舵机丝滑运转附代码

使用STM32F103C8T6控制舵机丝滑运转原理和案例,附代码。

m0_63566592的博客 4237

Qt多线程之QThread

进程:是各种资源的容器,它定义了一个地址空间作为基本的执行环境线程:是一个指令执行的序列,它可以直接访问所属进程中的资源。每个进程都至少有一个线程,每个线程再任一时刻都一定属于某一特定的进程。​​。

weixin_41843457的博客 1629

Bellhop水声信道模型的仿真

Bellhop是一种基于射线追踪的水声信道模型,广泛用于预测水下环境中的声压场。它通过模拟声波在水中的传播路径,计算声场分布,适用于复杂的水下通信场景。

yt94832的博客 1309

Halcon 简单的形状匹配定位与区域跟随

【代码】Halcon简单的形状匹配定位与区域跟随。

唐大狗 2806

掌握Qt的QThread:深入多线程编程

QThread是 Qt 中用于执行线程的类。它允许你将耗时的任务移到后台线程执行,从而不会阻塞用户界面。你需要确保你的任务类继承自QObject并重写runQ_OBJECTpublic:// 执行耗时任务。

dont worry about it的博客 2万+

奥比中光Dabai深度相机SDK在Ubuntu22.04的兼容性安装指南

本文详细指导如何在Ubuntu22.04系统上安装奥比中光Dabai深度相机的SDK。针对新旧版本不兼容的核心问题,重点推荐使用经过验证的v1.10.18版本SDK,并提供了从系统依赖检查、SDK下载安装、Python环境配置到编译测试的完整步骤,帮助用户成功解决安装难题并实现相机驱动。

j2k3l4的博客 999

C++ Qt开发:运用QThread多线程组件

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用`QThread`组件实现多线程功能。

微软技术分享 5151

Materials Studio实战技巧(八)——利用片段库高效构建有机金属配合物

本文详细介绍了在Materials Studio中利用Fragment Browser(片段浏览器)高效构建有机金属配合物的实战技巧。通过调用预置的Metal Templates和Ligands库,用户可以快速搭建如茂金属催化剂等复杂分子骨架,并利用对称性操作精确控制Meso与Rac构型。文章还涵盖了自定义片段库的创建与使用,能显著提升建模效率,适用于计算化学与材料模拟领域的研究者。

wine的专栏 935

虚拟机扩容——非LVM分区

虚拟机扩容——非LVM分区

ytraister的博客 3905

Qt 串口多线程 继承QThread

前两节分别介绍了Qt串口收发及通过子线程实现收发的功能,本节将介绍通过继承QThread类来实现相同的串口收发功能。

Rough Set 2879

(04730)半导体器件之基本放大器工作原理(一)

放大器是构成各种电子线路的基本单元电路。所谓“放大”,就是将输入的微弱信号(微弱变化的电压或电流等)去控制直流电源提供的能量,并使输出按照输入的小信号变化规律而变化的过程。所以放大器的本质是能量转换器。本节重点学习基本放大电路的工作原理和基本分析方法及主要性能指标。

黄先生的博客 3005

Qt多线程1:QThread

QThread只有run函数是在新线程里的在QThread执行start函数之后,run函数还未运行完毕,再次start会出现什么后果?答案是:不会发生任何结果,QThread还是继续执行它的run函数,run函数不会被重新调用。return;这种调用方法估计了解过QThread的都知道在线程运行过程调用quit函数有什么效果答案是:不会发生任何效果,QThread不会因为你调用quit函数而退出正在运行到一半的run,正确退出线程的方法上面有介绍。

hw5230的博客 1777

用 Custom Entity 打造 RAP Value Help:从能跑到好用的深度踩坑笔记

本文介绍了在RAP项目中实现Value Help(Fiori输入帮助)的完整流程。通过Custom Entity方式,开发者可以灵活构建不依赖数据库实体的值帮助功能,但需手动实现CDS原本提供的过滤、排序、分页等能力。文章以一个典型场景为例,详细说明了如何为Partner维护界面的City字段创建可搜索的值帮助,包括创建查询实现类、绑定CDS Custom Entity、服务发布等关键步骤,并特别指出了处理排序分页请求等常见问题。最后强调在ABAP Cloud环境下需要自行实现查询能力,而非依赖传统工具类。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 134

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Qt多线程-QThread

QThread多线程实现投掷骰子功能

weixin_41918998的博客 1111

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

QT QThread 多线程操作

在QT中,QT应用程序所在的线程为主线程,也称为“GUI线程”,QT GUI必须运行在此线程上;而非主线程称为“工作者线程”,主要处理从主线程中卸下的一些工作,例如数据的同步访问等。需要明确的是,同一个进程的不同线程之间共享相同的地址空间。 什么时候应该使用线程? 如果一个应用程序需要处理一些耗时的数据计算时,应该用一个独立线程来做这些运算,这样用户可以提前中断或者暂停数据处理...

yhl_sophia的博客 8440

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Qt多线程的三种方法QThread

推荐做的:在QThread子类添加信号。这是绝对安全的,并且也是正确的(发送者的线程依附性没有关系)不应该做的是:调用moveToThread(this)函数指定连接类型:这通常意味着你正在做错误的事情,比如将QThread控制接口与业务逻辑混杂在了一起(而这应该放在该线程的一个独立对象中)在QThread子类添加槽函数:这意味着它们将在错误的线程被调用,也就是QThread对象所在线程,而不是QThread对象管理的线程。这又需要你指定连接类型或者调用moveToThread(this)函数。

hw5230的博客 3550

[QT编程系列-25]:多线程机制 - QThread和MoveToThread简介

QThread类提供了一个与平台无关的管理线程的方法。在Qt中建立线程的主要目的就是为了用线程来处理那些耗时的后台操作,比如大量运算,复制大文件,网络传输等。QT(也称为Qt框架)是一个用于开发跨平台应用程序的C++库。它提供了丰富的功能,包括多线程支持。多线程是一种在同一时间处理多个任务的技术,它可以改善应用程序的响应性和性能。

文火冰糖(王文兵)的博客 4428

Qt多线程- QThread 创建多线程程序

今天说一下 Qt 中的多线程。QThread类不依赖平台的管理线程的方法。一个QThread类的对象管理一个线程,一般从QThread继承一个自定义类,并重新定义虚函数run(),在run()函数里实现线程需要完成的任务。将应用程序的线程称为主线程,额外创建的线程称为工作线程。一般在主线程里创建工作线程,并调用start()开始执行工作线程的任务。start()会在内部调用run()函数,进入工作线程的事件循环,在run()函数里调用exit()或quit()可以结束线程的事件循环,或在主线程调用。

Lenn Louis' Scribe 1412

【QT八股文】系列之篇章3 | QT的多线程以及QThread与QObject

第一篇章主要是基础定义及QT中重要的事件机制【QT八股文】系列之篇章1 | QT的基础知识及事件/机制第二篇章主要是QT的信号与槽以及通讯流程【QT八股文】系列之篇章2 | QT的信号与槽及通讯流程这里我们主要件点更实际的,也就是多线程以及QThread与QObject因为介绍到信号与槽,所以笔者我会讲通讯流程提前在前面来介绍原创文章,未经同意请勿转载QThread 是 QT 中用于创建线程的类,它提供了一组方法用于启动、停止、监测线程的运行状态,以及获取线程的相关信息。

xiaobaizaza_Ry的博客 2576
上一篇: QSslSocket::connectToHostEncrypted: TLS initialization failed
下一篇: Qt中的遍历
不是很大锅
博客等级 码龄10年 34粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不是很大锅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值