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.rhkb.cn/news/331573.html

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

相关文章

Hive安装教程

前置条件:hadoop&mysql docker容器安装mysql-CSDN博客 以下的/opt/bigdata目录根据自己实际情况更改 1.上传hive包并解压 tar -zxvf apache-hive-3.1.3-bin.tar.gz -C /opt/bigdata/ 2.修改路径 mv /opt/bigdata/apache-hive-3.1.3-bin/ hive cd /opt/bigdata/hive/…

CIC滤波器

CIC滤波器结构简单&#xff0c;没有乘法器&#xff0c;只有加法器、积分器和寄存器&#xff0c;适合工作在高抽样率条件下&#xff0c;而且CIC滤波器是一种基于零点相消的FIR滤波器。 CIC滤波器分为单级和多级滤波器。 1.在单极滤波器中&#xff1a; 当CIC滤波器的长度M远大于…

MongoDB(介绍,安装,操作,Springboot整合MonggoDB)

目录 MongoDB 1 MongoDB介绍 MongoDB简介 MongoDB的特点 MongoDB使用场景 小结 2 MongoDB安装 安装MongoDB 连接MongoDB MongoDB逻辑结构 MongoDB数据类型 小结 3 MongoDB操作 操作库和集合 操作文档-增删改 操作文档-查询 MongoDB索引 小结 4 SpringBoot整合…

【微积分】CH16 integrals and vector fields听课笔记

【托马斯微积分学习日记】13.1-线积分_哔哩哔哩_bilibili 概述 16.1line integrals of scalar functions [中英双语]可视化多元微积分 - 线积分介绍_哔哩哔哩_bilibili 16.2vector fields and line integrals&#xff1a; work circulation and flux 向量场差不多也是描述某种…

kubernetes的服务发现

目录 概述集群内部ip访问ServiceDNSHeadlessService 集群内 --> 集群外集群外--> 集群内NodePortHostPortIngress 概述 本篇介绍kubernetes的服务发现&#xff0c;主要分三部分&#xff1a;k8s 集群内部互相通信、k8s 集群内部访问外部、集群外部访问集群内部。   解决…

数理逻辑:1、预备知识

17.1 命题和联结词 ​ 命题&#xff1a;可以判定真假的陈述句。&#xff08;则悖论&#xff0c;祈使句&#xff0c;疑问句都不是命题&#xff09; ​ 原子命题&#xff1a;不能被分割为更小的命题的命题 例如&#xff1a; 2既是素数又是偶数 可以由$p: 2 是素数&#xff0c;…

与用户沟通获取需求的方法

1 访谈 访谈是最早开始使用的获取用户需求的技术&#xff0c;也是迄今为止仍然广泛使用的需求分析技术。 访谈有两种基本形式&#xff0c;分别是正式的和非正式的访谈。正式访谈时&#xff0c;系统分析员将提出一些事先准备好的具体问题&#xff0c;例如&#xff0…

Linux网络编程(socket)

1. 概念 局域网和广域网 局域网&#xff1a;局域网将一定区域内的各种计算机、外部设备和数据库连接起来形成计算机通信的私有网络。广域网&#xff1a;又称广域网、外网、公网。是连接不同地区局域网或城域网计算机通信的远程公共网络。 IP&#xff08;Internet Protocol&a…

三维场景感知之三维目标检测方向入门

三维目标检测入门 1 文档需知2 基础知识深度学习基础必上手项目科研研究必知道的论文门户深度学习必看论文 3 目标检测入门知识二维目标检测必看论文 4 三维目标检测入门知识三维目标检测必熟悉数据集三维目标检测点云分类分割预备知识三维目标检测必熟悉&#xff0c;必跑通&am…

自由职业香吗?

啥叫自由职业&#xff1f; 就是有随时随地做事的自由 有不打卡的自由 有不被PUA的自由 有不开低效会议的自由 有不写PPT八股文的自由 也有赚钱或者赚不到钱的自由 我从不来不劝人离职&#xff0c;除非这家公司关了。除了你已经跑通自己的业务闭环。 其实很多idea 都经过MVP。蘑…

ViLT学习

多模态里程碑式的文章&#xff0c;总结了四种多模态方法&#xff0c;根据文字和图像特征特征抽取方式不通。 文章的贡献主要是速度提高了&#xff0c;使用了数据增强&#xff0c;文本的mask 学习自b站朱老师的论文讲解

PLSQL连接Linux Oracle21c

PLSQL连接Linux Oracle21c 一、安装PLsql 下载官网 https://www.allroundautomations.com/registered-plsqldev/ 二、Oracle Instant Client下载 使用plsql连接oracle的时候是需要本地先安装oracle客户端&#xff0c;英文名就是Oracle Instant Client。 官方下载地址&…

Java | Leetcode Java题解之第100题相同的树

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isSameTree(TreeNode p, TreeNode q) {if (p null && q null) {return true;} else if (p null || q null) {return false;}Queue<TreeNode> queue1 new LinkedList<TreeNode>();…

基于HTML5和CSS3搭建一个Web网页(二)

倘若代码中有任何问题或疑问&#xff0c;欢迎留言交流~ 网页描述 创建一个包含导航栏、主内容区域和页脚的响应式网页。 需求: 导航栏: 在页面顶部创建一个导航栏&#xff0c;包含首页、关于我们、服务和联系我们等链接。 设置导航栏样式&#xff0c;包括字体、颜色和背景颜…

【数据结构与算法 刷题系列】移除链表元素

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;数据结构与算法刷题系列&#xff08;C语言&#xff09; 期待您的关注 目录 一、问题描述 二、解题思路 三、源代码实现 一、问题…

HQL面试题练习 —— 互相关注

目录 1 题目2 建表语句3 题解 1 题目 现有用户关注者列表记录表 t_user_follower&#xff0c;有两个字段&#xff0c;用户ID&#xff08;user_id&#xff09;&#xff0c;关注者列表&#xff08;follower_ids)&#xff0c;关注者列表中是关注用户的用户ID&#xff0c;数据样例如…

go-zero 实战(3)

引入 Redis 在之前的 user 微服务中引入 redis。 1. 修改 user/internal/config/config.go package configimport ("github.com/zeromicro/go-zero/core/stores/cache""github.com/zeromicro/go-zero/zrpc" )type Config struct {zrpc.RpcServerConfMys…

java如何获取IP和IP的归属地?

在Java中&#xff0c;获取IP地址通常指的是获取本地机器的IP地址或者通过某种方式&#xff08;如HTTP请求&#xff09;获取的远程IP地址。代码案例如下: 而要获取IP的归属地&#xff08;地理位置信息&#xff09;&#xff0c;则通常需要使用第三方IP地址查询服务&#xff0c;我…

【C++ QT项目实战-03】---- C++ QT系统实现读取JSON文件数据的自动化模式

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a;C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &#…

解决在cmd里下载的库,但IDLE还是显示不存在的问题

原因一&#xff1a; 环境变量配置 首先&#xff0c;你需要确认你安装库的时候使用的Python环境是否和IDLE使用的Python环境是同一个。如果cmd中你使用的是系统路径下的Python&#xff0c;而IDLE使用的是另一个路径下的Python&#xff0c;那么你在cmd中下载的库&#xff0c;IDL…