Qt学习记录(14)线程

前言:

我的臀部已经翘到可以顶起一屁股债了

为什么要使用线程

什么时候用线程

复杂的数据处理

头文件.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTimer>//定时器头文件QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void dealTimeout();//定时器槽函数private slots:void on_pushButton_clicked();private:Ui::Widget *ui;QTimer *myTimer;//声明变量
};
#endif // WIDGET_H

.cpp文件 

#include "widget.h"
#include "ui_widget.h"
#include <QThread>
#include <QDebug>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);myTimer=new QTimer(this);//只要定时器启动,自动触发timeout()connect(myTimer,&QTimer::timeout,this,&Widget::dealTimeout);
}void Widget::dealTimeout()
{static int i =0;i++;//设置LCD的值ui->lcdNumber->display(i);
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{//如果定时器没有工作if(myTimer->isActive()==false){myTimer->start(100);}//非常复杂的数据处理,耗时较长QThread::sleep(5);//处理完数据,关闭定时器myTimer->stop();qDebug()<<"over";
}

 现象

忘了录,而且不好展示,当按下start按键的时候,整个页面会卡住,不可移动和点击,LCD也没有变化,5秒后打印"over"

线程旧的用法

 

 添加QThread文件

添加新文件

 注意基类选择object

 .h和.cpp文件改基类和头文件

运行检查是否有错

QThread F1查询 Protected Function

protected://QThread的虚函数//线程处理函数//不能直接调用,通过start()间接调用void run();

 QThread的使用

mythread.h 线程头文件

#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QThread>class MyThread : public QThread
{Q_OBJECT
public:explicit MyThread(QObject *parent = nullptr);
protected://QThread的虚函数//线程处理函数//不能直接调用,通过start()间接调用void run();
signals:void isDone();};#endif // MYTHREAD_H

mythread.cpp 线程主文件 

#include "mythread.h"MyThread::MyThread(QObject *parent) : QThread(parent)
{}void MyThread::run()
{//很复杂的数据处理//需要耗时5ssleep(5);emit isDone();
}

 widget.h主窗口头文件

添加了线程头文件,线程槽函数,线程停止函数,线程对象

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTimer>//定时器头文件
#include "mythread.h"//线程头文件QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void dealTimeout();//定时器槽函数void dealDone();//线程槽函数void stopThread();//停止线程槽函数
private slots:void on_pushButton_clicked();private:Ui::Widget *ui;QTimer *myTimer;//声明变量MyThread *thread;//线程对象
};
#endif // WIDGET_H

 widget.cpp 主窗口主文件

#include "widget.h"
#include "ui_widget.h"
#include <QThread>
#include <QDebug>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);myTimer=new QTimer(this);//只要定时器启动,自动触发timeout()connect(myTimer,&QTimer::timeout,this,&Widget::dealTimeout);//分配空间thread = new MyThread(this);connect(thread,&MyThread::isDone,this,&Widget::dealDone);//当按窗口右上角x时,窗口触发destroyed()信号connect(this,&Widget::destroyed,this,&Widget::stopThread);
}
void Widget::stopThread()
{//停止线程thread->quit();//等待线程处理完手中工作thread->wait();  
}void Widget::dealDone()
{qDebug()<<"it is over";myTimer->stop();
}
void Widget::dealTimeout()
{static int i =0;i++;//设置LCD的值ui->lcdNumber->display(i);
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{//如果定时器没有工作if(myTimer->isActive()==false){myTimer->start(100);}//启动线程,处理数据thread->start();
}

现象

5秒停止,打印"it is over"

线程新的用法

 

mythread.h头文件

#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QObject>class MyThread : public QObject
{Q_OBJECT//如果没有这个宏就会报错
public:explicit MyThread(QObject *parent = nullptr);//线程处理函数void myTimeout();void setFlag(bool flag=true);signals:void mySignal();private:bool isStop;};#endif // MYTHREAD_H

 

mythread.cpp文件

#include "mythread.h"
#include <QThread>
#include <QDebug>
#include <QMessageBox>MyThread::MyThread(QObject *parent) : QObject(parent)
{isStop=false;
}void  MyThread::myTimeout()
{while(isStop==false){QThread::sleep(1);emit mySignal();//QMessageBox::aboutQt(NULL);qDebug()<<"子线程号:"<<QThread::currentThread();if(true==isStop){break;}}}void MyThread::setFlag(bool flag)
{isStop=flag;
}

 

widget.h头文件

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "mythread.h"
#include <QThread>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void dealSignal();void dealClose();
signals:void startThread();//启动子线程的信号private slots:void on_ButtonStart_clicked();void on_ButtonStop_clicked();private:Ui::Widget *ui;MyThread *myT;QThread *thread;};
#endif // WIDGET_H

widget.cpp文件

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//动态分配空间,不能指定父对象//指定父对象后,不能movemyT =new MyThread;//创建子线程thread =new QThread(this);//把自定义的线程加入到子线程中myT->moveToThread(thread);connect(myT,&MyThread::mySignal,this,&Widget::dealSignal);qDebug()<<"主线程号:"<<QThread::currentThread();connect(this,&Widget::startThread,myT,&MyThread::myTimeout);connect(this,&Widget::destroyed,this,&Widget::dealClose);//线程处理函数内部,不允许操作图形界面//connect()第五个参数的作用,连接方式:默认,队列,直接//多线程才有意义,//默认的时候//如果是多线程,默认使用队列//如果是单线程,默认使用直接方式//队列:槽函数所在线程和接收者一样//直接:槽函数所在线程和发送者一样
}Widget::~Widget()
{delete ui;
}void Widget::dealClose()
{on_ButtonStop_clicked();delete myT;
}void Widget::dealSignal()
{static int i=0;i++;ui->lcdNumber->display(i);}
void Widget::on_ButtonStart_clicked()
{if(thread->isRunning()==true){return;}//启动线程,但是没有启动线程处理函数thread->start();myT->setFlag(false);//不能直接调用线程处理函数//直接调用会导致线程处理函数和主线程是在同一个线程//myT->myTimeout();//只能通过 signal-slot方式调用emit startThread();
}void Widget::on_ButtonStop_clicked()
{if(thread->isRunning()==false){return;}myT->setFlag(true);thread->quit();//线程手头工作处理不完thread->wait();
}

现象

 在黑马的视频里面说,线程内部不能处理图形,但是我这里是运行出来的了,QMessageBox,但是后面又出问题,闪退了

线程画图

流程

mythread.h头文件

#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QImage>
#include <QObject>class MyThread : public QObject
{Q_OBJECT
public:explicit MyThread(QObject *parent = nullptr);//线程处理函数void drawImage();
signals:void updateImage(QImage temp);};#endif // MYTHREAD_H

mythread.cpp文件

#include "mythread.h"
#include<QPainter>
#include <QPen>
#include <QBrush>
#include <QThread>
MyThread::MyThread(QObject *parent) : QObject(parent)
{}
void MyThread::drawImage()
{//定义QImage绘图设备QImage image(500,500,QImage::Format_ARGB32);//定义画家,指定绘图设备QPainter p(&image);//定义画笔对象QPen pen;pen.setWidth(5);//设置宽度//把画笔交给画家p.setPen(pen);//定义画刷QBrush brush;brush.setStyle(Qt::SolidPattern);//设置样式brush.setColor(Qt::red);//设定颜色//把画刷交给画家p.setBrush(brush);//定义5个点QPoint a[] ={QPoint(qrand()%500,qrand()%500),QPoint(qrand()%500,qrand()%500),QPoint(qrand()%500,qrand()%500),QPoint(qrand()%500,qrand()%500),QPoint(qrand()%500,qrand()%500)};p.drawPolygon(a,5);//通过信号发送图片emit updateImage(image);}

widget.h头文件

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "mythread.h"
#include <QThread>
#include <QImage>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();//重写绘图事件void paintEvent(QPaintEvent *);void getImage(QImage temp);void dealClose();//窗口关闭槽函数private:Ui::Widget *ui;QImage image;MyThread *myT;//自定义线程对象QThread *thread;
};
#endif // WIDGET_H

widget.cpp文件

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QThread>
#include <QPushButton>
#include <QImage>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//自定义类对象,分配空间,不可以指定父对象myT=new MyThread;//创建子线程thread=new QThread(this);//把自定义模块添加到子线程myT->moveToThread(thread);//启动子线程,但是并没有启动线程处理函数thread->start();//线程处理函数,必须通过signal -solt调用connect(ui->pushButton,&QPushButton::pressed,myT,&MyThread::drawImage);connect(myT,&MyThread::updateImage,this,&Widget::getImage);connect(this,&Widget::destroyed,this,&Widget::dealClose);}Widget::~Widget()
{delete ui;
}
void Widget::dealClose()
{//退出子线程thread->quit();//回收资源thread->wait();delete myT;}
void Widget::getImage(QImage temp)
{image=temp;update(); //更新窗口,间接调用painEvent()}void Widget::paintEvent(QPaintEvent *)
{QPainter p(this);//创建画家,指定绘图设备为窗口p.drawImage(50,50,image);
}

现象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/15317.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python+Flask+Pandas怎样实现任意时间范围的对比数据报表

话不多说,有图有源码: 1.上图 2.因为是低代码的,只能发重要有用的代码片段了 实现思路:1)获取指定时间范围内的数据:2)df合并 #----------年份替换----------------for syear in range(int(byear),int(eyear)1):start_datestr(syear)strbdate[4:]end_datestr(syear)stredate…

【大数据】MapReduce JAVA API编程实践及适用场景介绍

目录 1.前言 2.mapreduce编程示例 3.MapReduce适用场景 1.前言 本文是作者大数据系列专栏的其中一篇&#xff0c;前文我们依次聊了大数据的概论、分布式文件系统、分布式数据库、以及计算引擎mapreduce核心概念以及工作原理。 书接上文&#xff0c;本文将会继续聊一下mapr…

光源亮度检测应用笔记

光源亮度检测应用笔记 光电检测应用光电二极管等效模型和基本参数连接并联电阻&#xff08;RJ&#xff09;串联电阻&#xff08;RS&#xff09;结电容&#xff08;CJ&#xff09;暗电流&#xff08;ID&#xff09; 光电二极管电流-电压转换器无源光电二极管电流-电压转换器有源…

C++ Primer 第五版 第十三章 拷贝控制

当定义一个类时&#xff0c;我们显式地或隐式地指定在此类型的对象拷贝、移动、赋值和销毁时做什么。一个类通过定义五种特殊的成员函数来控制这些操作&#xff0c;包括&#xff1a;拷贝构造函数&#xff08;copy constructor&#xff09;、拷贝赋值运算符&#xff08;copy-ass…

柯桥职场人出差必备的商务口语-职场差旅口语提问篇

May I reconfirm my flight? 我可以确认我的班机15857575376吗&#xff1f; Where can I make a reservation? 我到哪里可以预订&#xff1f; Do I have to make a reconfirmation? 我还要再确认吗&#xff1f; Is there any discount for the USA Railpass? 火车通行…

node.js —— 解读http模块

目录 http模块&#xff1a; http模块的引入&#xff1a; 创建web服务器的基本步骤&#xff1a; web服务器的一些基本属性&#xff1a; 上述知识汇总案例&#xff1a; http模块&#xff1a; http模块的引入&#xff1a; const http require (http) 创建web服务器的基本步骤…

探索未来,与移动云共舞

探索未来&#xff0c;与移动云共舞 在数字化飞速发展的今天&#xff0c;云计算已经成为企业、政府乃至个人用户不可或缺的一部分。而在众多云服务提供商中&#xff0c;移动云凭借其独特的优势&#xff0c;为用户带来前所未有的体验。接下来&#xff0c;让我们一起走进移动云的世…

LeetCode题练习与总结:从中序与后序遍历序列构造二叉树--106

一、题目描述 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7], postorder [9,15,7,20,3] 输出…

等保三级云防火墙正版--免费部署满足要求

正版授权内部部署配置授权免费 1、超时退出 2、病毒防护 3、防火墙策略 4、密码复杂度和登录失败处理 5、特征库 点赞关注 私信获取 获取授权 Q 8-5-0-3-4-7-3-3-5

MCU复位电路

【单片机复位电路&#xff0c;巧妙的RC无处不在。】https://www.bilibili.com/video/BV1XW4y1571r?vd_source3cc3c07b09206097d0d8b0aefdf07958 左侧的RESET引脚正常情况下是低电平&#xff0c;是高电平复位&#xff1b;右侧的RESET引脚正常情况下是高电平&#xff0c;是低电…

【电源专题】什么是局部放电(Partial Discharge)

什么是局部放电? 当电压施加在含有两个以上绝缘材料的绝缘物体时,有一个绝缘材料发生放电且至少仍有一个绝缘材料维持正常的绝缘状态,此放电现象称之为局部放电(Partial Discharge)。 举例来说,当待测物的绝缘材料中存在异常气隙,因为空气的介电系数比绝缘材料低以及空气的…

家政服务,让您的家更温馨

家&#xff0c;是我们生活的港湾&#xff0c;也是我们心灵的归宿。在这个快节奏的时代&#xff0c;每个人都在为了生活而奔波。然而&#xff0c;家务琐事却常常成为我们忙碌生活中的绊脚石。为了解决这个问题&#xff0c;家政行业应运而生&#xff0c;为您的生活带来便利与舒适…

vite搭建React+ts+eslint+prettier

一、vite搭建ts模板 npm create vitelatest 项目名 -- --template react-ts//进入到项目文件夹 npm inpm run dev 初始化完成后已经配置好eslint src下一般只留下 初始化git仓库(可选) git init . 二、配置prettier npm i prettier eslint-config-prettier eslint-plugi…

【论文速读】GPT-1:Improving Language Understanding by Generative Pre-Training

摘要 自然语言理解包括广泛的不同的任务&#xff0c;如文本隐含、问题回答、语义相似性评估和文档分类。虽然大量的未标记文本语料库非常丰富&#xff0c;但用于学习这些特定任务的标记数据非常稀缺&#xff0c;这使得经过区别训练的模型要充分执行任务具有挑战性。我们证明&a…

Ubuntu(22.04)不能上网解决办法

想必大家可能在别的贴子看到用以下指令的方法&#xff0c;但是在22版本的ubuntu是行不通的&#xff0c;问题在于22版本中网络管理器的名字压根不是network-manager&#xff0c;而是 NetworkManager. sudo service network-manager stop sudo rm /var/lib/NetworkManager/Netw…

短剧APP开发,短剧行业发展下的财富密码

今年以来&#xff0c;短剧市场展现出了繁荣发展的态势&#xff0c;成为了一个风口赛道。 短剧具有不拖沓、时长短、剧情紧凑等优势&#xff0c;顺应了当代人的生活&#xff0c;是当代人的“电子榨菜”。 短剧的快速发展同时也带动了新业态新模式的发展&#xff0c;短剧APP就是…

ClickHouse vs. Elasticsearch: 计数聚合的工作原理

本文字数&#xff1a;7875&#xff1b;估计阅读时间&#xff1a;20 分钟 审校&#xff1a;庄晓东&#xff08;魏庄&#xff09; 介绍 在另一篇博客文章中&#xff0c;我们对 ClickHouse 和 Elasticsearch 在大规模数据分析和可观测性用例中的性能进行了比较&#xff0c;特别是对…

python-找出四位数中的玫瑰花数

【问题描述】玫瑰花数指一个n位数&#xff08;n>4),其每位上的数字的n次幂之和等于本身。 请求出所有四位数中的玫瑰花数 【输入形式】 【输出形式】 【样例输入】 【样例输出】1634 8208 9474 【样例说明】 【评分标准】 完整代码如下&#xff1a; for n in ra…

《计算机网络微课堂》1-2:因特网概述

1-2&#xff1a;因特网概述 网络、互连网&#xff08;互联网&#xff09;和因特网因特网发展的三个阶段因特网的标准化工作因特网的组成 ‍ 网络、互连网&#xff08;互联网&#xff09;和因特网 我们首先介绍网络、互联网&#xff08;互连网&#xff09;因特网的基本概念&a…

ensp-三层交换技术

交换机-三层交换 一.概述 单臂路由有明显的缺陷,单臂路由的链路使用率高,可能会造成网路拥塞,造成网络不可用 可以让多个交换机连接路由器的不同接口,但是路由器的接口毕竟有限,不像交换机一样有那么多接口 使用三层交换解决路由器接口不够用问题 二.三层交换 1.创建多个VLAN…