首页 > 其他分享 >Qt线程使用

Qt线程使用

时间:2024-09-07 15:20:51浏览次数:13  
标签:Widget include Qt 线程 使用 SubThread QThread 函数

嗨嗨嗨,今天又学到了新的知识——线程,这个玩意在项目中使用的频率是非常高的,毕竟电脑的主线程就那么一个,那么这也就是我们为啥要学习线程的原因。比如说,我们们的游戏,如果我们的游戏界面显示的同时我们可以操作我们的装备、地图、人物移动等等这些都是线程做的,这样可以在一定程度上实现并行处理的效果,(虽然它还是串行的)。那我们开始发车了!!!!

1.UI界面

首先我们先设置我们的UI界面毕竟要看到效果嘛

就这样简单,一个按钮加一个TextEdit。

2.subthread类的创建

我们新建一个类,我们将我们的线程和我们的主Widget类分开,这样编辑的时候方便,

这个应该都会吧~~~

编辑subthread.h

#ifndef SUBTHREAD_H  // 检查SUBTHREAD_H是否已定义,防止头文件重复包含
#define SUBTHREAD_H

#include <QObject>  // 包含QObject类,因为SubThread类继承自QObject

class SubThread : public QObject  // 定义一个继承自QObject的类SubThread
{
    Q_OBJECT  // 启用Qt的信号和槽机制

public:
    explicit SubThread(QObject *parent = nullptr);  // 构造函数,允许将父对象设置为nullptr

public slots:  // 定义槽函数区域
    void Run();  // 定义一个槽函数Run,可以在Qt的信号槽机制中被调用

signals:  // 定义信号区域
    void SendData(int cnt);  // 定义一个信号SendData,当需要发送数据时发出,参数为int类型

};

#endif // SUBTHREAD_H  // 结束头文件保护

这个里面大致和Widget里的初始内容大差不差,就是定义了一个信号,毕竟我们要在线程中创建函数,实现完成之后要将参数用信号传给主线程嘛

编辑subthread.cpp

#include "subthread.h"
#include "QThread"
#include"QWidget"

// SubThread类的构造函数
SubThread::SubThread(QObject *parent)
    : QObject{parent} // 调用QObject的构造函数,传入父对象指针
{}

// SubThread类的槽函数Run,用于在子线程中执行的任务
void SubThread::Run()
{
    int cnt = 10; // 初始化计数器为10
    while (cnt > 0) { // 当计数器大于0时循环

        emit SendData(cnt--); // 发出SendData信号,传递当前计数器值,并递减计数器
        QThread::msleep(1000); // 使当前线程暂停1000毫秒(即1秒)
    }
    QThread::currentThread()->quit(); // 请求当前线程的事件循环退出

}


我们在这个类里来实现我们的子线程函数

3.Widget的编写

Widget.h的编写

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include"QThread"

QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget // 声明Widget类,它继承自QWidget
{
    Q_OBJECT // 宏,用于支持Qt的信号和槽机制

public:
    Widget(QWidget *parent = nullptr); // 构造函数,允许传入一个父QWidget指针
    ~Widget(); // 析构函数

private slots: // 私有槽函数,只能通过信号和内部连接来调用
    void on_pushButton_clicked(); // 当某个按钮被点击时调用的槽函数(假设是由Qt Designer自动连接的)
    void ReceiveData(int cd); // 接收数据的槽函数,参数为整型

private:
    Ui::Widget *ui; // 指向UI界面对象的指针(注意:这里应该是Ui_Widget,但按照您的代码保留)
    QThread *thread; // 指向QThread对象的指针,用于管理子线程
};

#endif // WIDGET_H // 结束头文件保护

在主函数里定义了一个槽函数,用来接收子线程信号的参数

Widget.cpp的编写

#include "widget.h"
#include "ui_widget.h"
#include "QThread"
#include "subthread.h"

// Widget类的构造函数
Widget::Widget(QWidget *parent)
    : QWidget(parent) // 调用基类的构造函数,传入父对象指针
    , ui(new Ui::Widget) // 实例化UI界面对象
{
    ui->setupUi(this); // 初始化UI界面
    // 创建QThread对象,作为子线程
    thread = new QThread(this);
    // 在堆上创建SubThread对象,SubThread是继承自QObject的类,用于在子线程中执行任务
    SubThread *st = new SubThread;
    // 将SubThread对象移动到QThread对象(子线程)中
    st->moveToThread(thread);
    // 当子线程结束时,自动删除SubThread对象
    connect(thread, &QThread::finished, st, &SubThread::deleteLater);
    // 当子线程启动时,调用SubThread的Run槽函数
    connect(thread, &QThread::started, st, &SubThread::Run);
    // 连接SubThread的SendData信号到Widget的ReceiveData槽函数
    connect(st, &SubThread::SendData, this, &Widget::ReceiveData);
}

// Widget类的析构函数
Widget::~Widget()
{
    delete ui; // 释放UI界面对象占用的内存
    // 安排QThread对象在事件循环结束时删除,确保线程安全退出
    thread->deleteLater();
}

// 槽函数,响应按钮点击事件
void Widget::on_pushButton_clicked()
{
    // 启动子线程
    thread->start();
    // 禁用按钮,防止在任务执行期间重复点击
    ui->pushButton->setDisabled(true);
}

// 槽函数,接收来自SubThread的SendData信号
void Widget::ReceiveData(int cd)
{
    // 将接收到的整数数据转换为QString,并追加到textEdit控件中
    ui->textEdit->append(QString::number(cd));
}

运行效果:

每一秒执行一次cnt--。

这样的效果就是,如果处理一个比较耗费时间的函数或事件的时候,我们将他交给子线程,他处理完成之后,将参数传上来就可以。

好嘞,大概就这样的,大家最好自己实现一下,然后多看看,要不然···········反正我一遍看不懂~~~~~

标签:Widget,include,Qt,线程,使用,SubThread,QThread,函数
From: https://blog.csdn.net/weixin_70293633/article/details/141996489

相关文章

  • 条款03: 尽可能使用const
    1.在classes外部修饰global或namespace作用域内的常量,或修饰文件、函数、或区块作用域中被声明为static的对象2.修饰classes内部的static和non-static成员变量3.可以指出指针自身、指针所指之物,或两者都不是,都是constchargreeting[]="Hello";char*constp00=greeting;......
  • ChatGPT 3.5/4.0新手使用手册
    ChatGPT3.5/4.0是一种强大的自然语言处理模型,可以用于各种对话任务。以下是一些使用ChatGPT3.5/4.0的初学者指南:了解模型能力:ChatGPT3.5/4.0在多个语言和主题领域上都有很高的能力,可以回答问题、产生语言文本、解决任务等。但它也有一些限制,例如在处理敏感主题和提供准确......
  • Linux网络操作的通用接口:Socket是怎么使用的?
    前言如果你在工作学习中经常见到socket相关的字眼,但总是未曾深究过其本质,相信这篇文章能够给你带来一些帮助。网络是计算机体系中绕不开的一环,而socket作为计算机网络体系的重要组成部分,也具备着相当重要的地位。但很多时候,虽然在书本或课堂上了解了TCP、IP等基础网络内容......
  • 11. MyBatis的一级缓存和二级缓存有什么区别?如何配置和使用二级缓存?
    在MyBatis中,缓存机制用于减少数据库访问次数,提高应用程序性能。MyBatis提供了两级缓存:一级缓存和二级缓存。1.一级缓存(LocalCache)作用范围:一级缓存作用于SqlSession级别。即在同一个SqlSession中执行相同的SQL查询,如果查询参数相同,MyBatis会从缓存中直接返回......
  • restful @RequestParam 可选,服务中的mock方法使用
    @RequestParam是一个SpringMVC注解,用于将请求参数绑定到你的方法参数上。当你标记一个参数为可选的时候,你可以不提供这个参数,在这种情况下,Spring将会使用这个参数的默认值,或者如果你没有设置默认值,它会使用参数的类型的默认值(例如,对于一个int类型的参数,默认值为0)。要将@......
  • Qt C++编程 从入门到实践 彭源 清华大学出版社
    第一章程序设计基础1.2.1输入和输出操作iostream叫做标准输入输出流库头文件namespacestd叫做标准命名空间cout、cin叫做标准输出、输入流对象有时候看见std::cout的代码,是因为没有事先声明cout对象是从标准命名空间调用的,::叫做域解析运算符,作用就是指明cout这个对象是......
  • MySQL触发器trigger的使用
    Q:什么是触发器?A:触发器是与表有关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合。触发器的特性:1、有beginend体,beginend;之间的语句可以写的简单或者复杂2、什么条件会触发:I、D、U3、什么时候触发:在增删改前或者后4、触发频率:针对......
  • 使用 nuxi prepare 命令准备 Nuxt 项目
    title:使用nuxiprepare命令准备Nuxt项目date:2024/9/7updated:2024/9/7author:cmdragonexcerpt:摘要:本文介绍nuxiprepare命令在Nuxt.js项目中的使用,该命令用于创建.nuxt目录并生成类型信息,以便于构建和部署。文章涵盖了命令的基本用法、指定根目录、设置日志级......
  • MySQL 性能压测工具-sysbench使用详解
    sysbench是一个开源的、基于LuaJIT(LuaJIT是Lua的即时编译器,可将代码直接翻译成机器码,性能比原生lua要高) 的、可自定义脚本的多线程基准测试工具,也是目前用得最多的MySQL性能压测工具。基于sysbench,我们可以对比MySQL在不同版本、不同硬件配置、不同参数(操作系统和数据......
  • MAX3485芯片使用总结
    芯片管脚介绍1.11号引脚为RO,通常与MCUUART控制器的RX相连接,用于接收对端数据。1.22号引脚为RE,RE对RO起控制作用,RE为低电平,RO可接收数据,RE为高电平时,RO不接收数据。1.33号引脚为DE,DE对DI起控制作用,DE为高电平,DI可输出数据,DE为低电平时,DI不输出数据。1.44号引脚为......