QThread介绍

2023-11-19

一、介绍

Qt中的QThread类提供了与平台无关的线程。一个QThread代表了一个在应用程序中可以独立控制的线程,它与进程中的其他线程分享数据,但是是独立执行的。

相对于一般的程序都从main()函数开始执行,QThread从run()函数开始执行。默认的,run()通过调用exec()来开启事件循环,并在线程内运行一个Qt事件循环。QThread的使用方法有如下两种:

1.使用QObject::moveToThread()

2.直接继承QThread类

二、使用moveToThread

首先新建一个work类,该类重点在于其doWork槽函数,这个函数定义了线程需要做的工作,需要向其发送信号来触发。

Worker.h

// work定义了线程要执行的工作
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include<QDebug>
#include<QThread>

class Worker :public QObject
{
    Q_OBJECT
public:
    Worker(QObject* parent = nullptr) {}
public slots:
    // doWork定义了线程要执行的操作
    void doWork(int parameter)
    {
        qDebug() << "receive the execute signal---------------------------------";
        qDebug() << "     current thread ID:" << QThread::currentThreadId();
        // 循环一百万次
        for (int i = 0; i != 1000000; ++i)
        {
            ++parameter;
        }
        // 发送结束信号
        qDebug() << "      finish the work and sent the resultReady signal\n";
        emit resultReady(parameter);
    }

    // 线程完成工作时发送的信号
signals:
    void resultReady(const int result);
};

#endif // WORKER_H

然后定义一个Controller类,这个类中定义了一个QThread对象,用于处理worker对象的事件循环工作 。

Controller.h

#ifndef CONTROLLER_H
#define CONTROLLER_H
#include <QObject>
#include<QThread>
#include<QDebug>

// controller用于启动线程和处理线程执行结果
class Controller : public QObject
{
    Q_OBJECT
        QThread workerThread;
public:
    Controller(QObject *parent = nullptr);
    ~Controller();

public slots:
    // 处理线程执行的结果
    void handleResults(const int rslt)
    {
        qDebug() << "receive the resultReady signal---------------------------------";
        qDebug() << "     current thread ID:" << QThread::currentThreadId() << '\n';
        qDebug() << "     the last result is:" << rslt;
    }
signals:
    // 发送信号触发线程
    void operate(const int);

};

#endif // CONTROLLER_H

 Controller类的cpp文件,其构造函数中创建worker对象,并且将其事件循环全部交给workerThread对象来处理,最后启动该线程,然后触发其事件处理函数。 

Controller.cpp

#include "Controller.h"
#include "Worker.h"

Controller::Controller(QObject *parent) : QObject(parent)
{
    Worker *worker = new Worker;

    //调用moveToThread将该任务交给workThread
    worker->moveToThread(&workerThread);

    //operate信号发射后启动线程工作
    connect(this, SIGNAL(operate(const int)), worker, SLOT(doWork(int)));

    //该线程结束时销毁
    connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);

    //线程结束后发送信号,对结果进行处理
    connect(worker, SIGNAL(resultReady(int)), this, SLOT(handleResults(int)));

    //启动线程
    workerThread.start();

    //发射信号,开始执行
    qDebug() << "emit the signal to execute!---------------------------------";
    qDebug() << "     current thread ID:" << QThread::currentThreadId() << '\n';
    emit operate(0);
}

//析构函数中调用quit()函数结束线程
Controller::~Controller()
{
    workerThread.quit();
    workerThread.wait();
}

main.cpp

#include <QCoreApplication>
#include "controller.h"
#include<QDebug>
#include<QThread>

int main(int argc, char *argv[])
{
    qDebug()<<"I am main Thread, my ID:"<<QThread::currentThreadId()<<"\n";
    QCoreApplication a(argc, argv);

    Controller c;
    return a.exec();
}

运行

三、继承QThread的方法

如果使用子类化QThread的方法,就是重写了QThread中的run()函数,在run()函数中定义了需要的工作。这样的结果是,我们自定义的子线程调用start()函数后,便开始执行run()函数

③定义TestThread对象并调用该对象的start方法运行

TestThread.h代码如下:

    #ifndef TESTTHREAD_H
    #define TESTTHREAD_H
     
    #include <QObject>
    #include <QThread>
     
    class TestThread : public QThread
    {
        Q_OBJECT
    public:
        explicit TestThread(QObject *parent = nullptr);
     
    private:
        //重写run方法
        void run();
     
    signals:
        //定义信号
        void ShowDownloadProgress(int progress);
     
    public slots:
    };

     
    #endif // TESTTHREAD_H

TestThread.cpp代码如下:

    #include "TestThread.h"
     
    TestThread::TestThread(QObject *parent) : QThread(parent)
    {
     
    }
     
    void TestThread::run()
    {
        for(int i = 0 ; i <= 100 ; i++)
        {
            QThread::msleep(100);
            ShowDownloadProgress(i);
        }
    }

   新建MyController.h

#include <QObject>
#include <QThread>
#include <QDebug>
#include "TestThread.h"

class MyController : public QObject
{
    Q_OBJECT
        QThread workerThread;
public:
    MyController() {
        TestThread *workerThread = new TestThread();
        connect(workerThread, SIGNAL(ShowDownloadProgress(int)), this, SLOT(ProgressLabelShow(int)));
        workerThread->start();
    }

    ~MyController() {
        workerThread.quit();
        workerThread.wait();
    }
public slots:
    void ProgressLabelShow(int value) {
        qDebug() << " current thread value:" << value <<"%"<< '\n';
    };
signals:
    // 发送信号触发线程
    void operate(const int );

};

 

在main.cpp中

#include <QVariant>
#include <QProcess>
#include<QDebug>
#include<QThread>
#include "MyController.h"
#include "TestThread.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "I am main Thread, my ID:" << QThread::currentThreadId() << "\n";

    MyController c;

    return a.exec();

}

运行

 参考:

QThread介绍_雪易的博客-CSDN博客_qthread

QThread的用法_落霞与孤鹜亓飞的博客-CSDN博客_qthread

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QThread介绍 的相关文章

  • 通过CMake实现Qt项目

    我正在尝试通过 Cmake 构建并运行非常简单且基本的 Qt 示例 删除 pro 文件 以下是Qt项目的代码 自动生成的Qt项目的目录结构为 Cmake my project name headers mainwindow h source
  • 如何通过 Qt 创建网络服务 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • QGraphicsScene没有删除QWidget的功能

    QGraphicsScene 有一个addWidget QWidget 有函数 但是没有对应的removeWidget QWidget 它只有removeItem QGraphicsItem 如何删除 QWidget 这是一个基本示例 看看
  • 如何在Qt无框窗口中实现QSizeGrip?

    如何使用 Qt 无框窗口实现 QSizeGrip 代码会是什么样的 您只需在布局内窗口的一角添加 QSizeGrip 即可使其保持在该角落 QDialog dialog new QDialog 0 Qt FramelessWindowHin
  • SWI-Prolog 与 C++ 接口的问题

    我试图让 SWI Prolog 与 C 很好地配合 现在束手无策 现在 在我开始准确解释我的问题是什么之前 我想首先说明我的项目是关于什么的以及我选择了哪些工具来开发解决方案 我的教授分配给我的任务是开发一个 GUI 程序 作为 SWI p
  • 如何为 qmlRegisterSingletonType 实现单例提供程序?

    我想在 QML 中使用 C 类作为 Singleton 实例 并认为我必须使用 qmlRegisterSingletonType 注册它们 此函数需要一个提供已注册 C 类的实例的函数 我在 Windows 上使用最新的 Qt 5 3 1
  • 仅在内部/外部抚摸路径?

    Given a QPainterPath http qt project org doc qt 4 8 qpainterpath html如何仅在路径的内侧或外侧边缘 或非闭合路径的左侧或右侧 描边路径 QPainter strokePat
  • 有没有办法向 QListView 添加部分?

    我正在使用 Qt5 2 和 C 来实现一个应用程序 需要显示一个列表 其中包含类似于下面的示例图像的部分 source ngo hung com http www ngo hung com files images contact list
  • 如何使用 Qt DOM 通过此语法获取 xml 属性

    我正在使用 Qt DOM XML 解析器 并且遇到了如下属性定义的问题
  • Qt qDebug() 在 Windows shell 中不起作用

    我正在使用一个qDebug Qt 框架的printf屏幕上有东西 当我从 Qt Creator 运行应用程序时它工作得很好 但是当我尝试从 Windows 执行它时cmd它什么也没显示 为什么会发生这种情况 你必须添加 CONFIG con
  • 在 QtCreator 中使用 .pro 和 .pri 正确(树)显示 Qt 项目

    是否可以使用项目包含文件 pri 显示不止一个额外级别 例如如果 pro文件包括 pri文件包含两个 pri files pro pri pri pri 在 QtCreator 项目 中显示具有误导性 pro pri pri pri 它根本
  • Qt 为什么使用 QString::number() 而不是 QLocale().toString()?

    我正在开发的应用程序将在许多国家推出 并且需要支持他们的语言 我一直在回顾我的代码并替换以下每个实例 QString number and QString toDouble with QLocale toString and QLocale
  • 使用 CMake 编译时更改头文件位置会导致缺少 vtable 错误

    对于一个大型 C 项目 我需要从 qmake 过渡到 CMake 但是在处理一个玩具示例时 我遇到了一些我不理解的行为 示例代码具有单个头文件 当该头文件移动到子目录中时 我收到 MainWindow 类缺少 vtable 的错误 CMak
  • Retina 显示屏中具有 QOpenGLWIdget 的 Qt MainWindow 显示错误大小

    我有一个 Qt 应用程序MainWindow 我嵌入一个QOpenGLWidget在里面 一切正常 直到我开始使用 Apple Retina 显示屏并在高 DPI 模式下运行我的应用程序 我的QOpenGLWidget只是它应该具有的大小的
  • 如何在针对 Windows XP 的情况下使用 VS2012 构建 Qt 4/5?

    我正在尝试使用 Visual Studio 2012 构建 Qt 4 8 5 Qt 5 2 1 针对 Windows XP SDK v7 1a 使用 VS2102 编译时 源代码与 SDK v7 1a 存在各种不兼容性 因此无法开箱即用 这
  • 如何在 Qt 应用程序中嵌入 Python 解释器?

    有没有一种简单的方法可以将 Python 解释器嵌入到 Qt 应用程序中 如果可能的话 我希望有一个跨平台的解决方案 这就是目的PythonQt http pythonqt sourceforge net 它支持 Windows Linux
  • 覆盖 QWebView 中的页面回复

    我试图在 Qt 的 QWebView 中拦截页面 表单请求 并在某些情况下使用替代内容进行响应 QNetworkReply ngcBrowser createRequest Operation operation const QNetwor
  • QTabWidget 选项卡在垂直方向,但文本在水平方向

    我正在尝试用 C Qt 制作一个带有这样的侧边栏的应用程序 但是当将 QTabWidget 方向设置为西时 它会使文本垂直 如何让文本位于左侧 但水平对齐 PS 我不需要图标 提前致谢 您可以使用QListWidget http doc q
  • QML 列表视图拖放

    我想创建两个 qml 列表视图 可以执行两个功能 拖放一个列表中的项目以更改项目的顺序 跨列表拖放项目 项目将从一个列表中删除并添加到另一个列表中 根据 Qt 文档中的拖放示例 我决定创建两个访问同一列表模型的列表视图 列表模型中的每个项目
  • Qt 支持 Windows 蓝牙 API 吗?

    谁能告诉我 Qt 是否支持 Windows 蓝牙 API 如果是这样 您能否分享一些有关如何使用它的信息 自上次答复以来 这个问题的答案发生了一些变化 Qt 5 2 版为 Linux BlueZ 和 BlackBerry 设备实现了蓝牙 A

随机推荐

  • Unraid使用记录:使用Docker与虚拟机

    文章目录 前言 使用Docker 使用示例 相关说明 使用虚拟机 使用示例 相关说明 硬件直通 后记 前言 Unraid本身功能挺少的 很多功能都是要通过插件 Docker和虚拟机来实现的 Docker可以简单的实现各种丰富的功能 而虚拟机
  • 群晖DS Video(Station)自动同步视频简介和海报(最新官方解决方案)

    目录 一 前言 二 前提 三 实现 1 注册The Movie Database账号 2 创建API 3 修改群辉Hosts A 在群辉中开启SSH的访问 B 然后通过ssh命令登录到群辉后台 C 通过sudo i指令切换到root用户指令
  • python的循环控制结构_Python的控制结构之For、While、If循环问题

    传统Python语言的主要控制结构是for循环 然而 需要注意的是for循环在Pandas中不常用 因此Python中for循环的有效执行并不适用于Pandas模式 一些常见控制结构如下 for循环 while循环 if else语句 tr
  • 【建议收藏!】APP UI自动化测试,思路全总结在这里了。

    首先想要说明一下 APP自动化测试可能很多公司不用 但也是大部分自动化测试工程师 高级测试工程师岗位招聘信息上要求的 所以为了更好的待遇 我们还是需要花时间去掌握的 毕竟谁也不会跟钱过不去 接下来 一起总结一下APP UI自动化测试的思路吧
  • 再论人与人的三大关系:生存关系、性关系和经济关系

    黄仁宇在 关系 一文中认为 人类的各种关系之中 以生存的关系 性关系和经济关系最为重要 理想上的工作协作和团队精神 已经不存在 俺做过的几个规模在50人以下的 这说明两个问题 1 小公司的目的不是发展而是不死 然后赚钱 也就是这是一笔买卖而
  • exe4j打包exe_JDK11及以后版本在Win下的打包发布方法

    概述 我在准备使用高版本jdk后 遇到的最麻烦的问题就是打包发布了 主要原因还是jdk的模块化带来的 在经历了长时间折腾后 终于成功完成了这个 当然 只是针对window下的 想要使用高版本jdk打包发布Windows应用 需要准备 exe
  • js中的对象 函数 原型

    关于 Function Object 和 proto prototype 1 每一个对象实例都有一个 proto 属性 这个属性就是指向 对象构造函数的原型 let b new Function console log b proto Fu
  • 【Matlab图片剪裁】

    标题Matlab剪裁图片 提取感兴趣部分 问题描述 当需要从一幅图片中提取一些感兴趣的内容时 比如一些细小的文字 图案等 如果从整个图片中直接提取 必然会大大增加计算量 导致处理时间很长 而且多数计算都是无效计算 进而非常消耗资源 解决办法
  • impala 错误

    问题一 impala state store unrecognized service 原因 当前节点未成功安装impala server impala state store impala catalog 解决方案 yum install
  • Qt生成log日志文件

    摘要 本文在Qt程序中实现了日志功能 读者可以在此基础上进一步创作和拓展 介绍 系统日志一般指存放系统重要运行信息的log txt文件 主要作用有两个 1 记录系统重要的运行信息 2 当系统突然崩溃时 可以根据日志来跟踪和定位程序错误 Qt
  • 常见CAD/CAM控件大全

    前言 CAD CAM 计算机辅助设计与制造 技术是随着计算机和数字化信息技术发展而形成的新技术 是20世纪最杰出的工程成就之一 也是数字化 信息化制造技术的基础 其发展和应用对制造业产生了巨大的影响和推动作用 经过几十年的发展和应用 不仅C
  • Python+Selenium爬虫之动态验证码的处理

    目录 1 拖动下方滑块完成拼图 单独图片 2 拖动下方滑块完成拼图 共同图片 可拖动验证码分为空缺区域为单独的图片和空缺区域与背景图片为一个共同图片 所以实现方式有2种 1 拖动下方滑块完成拼图 单独图片 拖动验证码 实现原理 查看空缺区域
  • [VScode]终端回应“pnpm : 无法将“pnpm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。“解决思路

    问题概述 遇到问题 在VScode终端输入pnpm install有错误提示 pnpm 无法将 pnpm 项识别为 cmdlet 函数 脚本文件或可运行程序的名称 请检查名称的拼写 如 果包括路径 请确保路径正确 然后再试一次 所在位置 行
  • wps表格中的文字不能顺利水平居中的解决办法

    今天调整别人做的表格 想要把表格中文字水平居中 竟然指令操作后发现很多行的表格无动于衷 发现这样设置一下应该可以解决 WPS文字右边有个小的下拉箭头 选择 格式 段落进行设置 段前段后设置为0 行距设置为单倍行距或者固定行距 固定行距需要测
  • maven私服不能重复部署解决方法

    maven私服不能重复部署解决 1 报错 Return code is 400 ReasonPhrase Repository does not allow updating assets maven releases 2 原因 经排查发现
  • Elasticsearch 7.x生产配置

    虽然Elasticsearch需要很少的配置 但是有一些设置需要手动配置 并且必须在进入生产之前进行配置 1 官方文档 这些重要配置说明 请参考官方文档 https www elastic co guide en elasticsearch
  • c++得到窗口句柄

    include
  • Gitlab Java API 使用示例(亲测、有效)

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 简介 一 依赖 常量 Maven依赖 定义常量类 二 增删改查 1 新增私有仓库 2 删除指定仓库 3 修改项目简介和是否开源 三 后续更新 简介 在开发中 偶尔会
  • 算法学习——动态规划的学习

    作者 小 琛 欢迎转载 请标明出处 引言 动态规划是算法中较难的内容 常常被用来区分学习者的档次 笔者也是在面试中发现了这个问题 故而回头认真学习并总结递归算法 希望能够帮助到阅读的你 文章目录 动态规划的思想 动态规划的具体实现步骤 入门
  • QThread介绍

    一 介绍 Qt中的QThread类提供了与平台无关的线程 一个QThread代表了一个在应用程序中可以独立控制的线程 它与进程中的其他线程分享数据 但是是独立执行的 相对于一般的程序都从main 函数开始执行 QThread从run 函数开