Qt 多线程专栏

article/2025/10/27 17:01:22
  • 主线程就是进程,进程代表4个G的资源空间,主线程退出就意味着进程退出,在Qt中,主线程不能是子线程的父对象,因此必须在线程的析构函数中去delete线程对象。

  • 只要定时器启动,自动触发timeout()信号

    • 类A继承了Tread类,在A中写run方法,就会覆盖掉Thread中的run方法,所以此时调用start方法后,实现的是自己的run方法体里面的代码。start()相当于间接的调用run(),如果我们直接调用子线程的run()方法,其方法还是运行在主线程中,代码在程序中是顺序执行的,所以不会有解决耗时操作的问题。所以不能直接调用线程的run()方法,只有子线程开始了,才会有异步的效果。当thread.start()方法执行了以后,子线程才会执行run()方法,这样的效果和在主线程中直接调用run()方法的效果是截然不同的。

    在这里插入图片描述
    在这里插入图片描述
    • 一个线程的创建基础格式如下: 在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    • 用子线程对象发送信号去开启线程函数: 在这里插入图片描述

于是这里就不需要改变了:
- ###

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

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();
private slots:void on_pushButton_2_clicked();void on_pushButton_clicked();signals:void startThread();//启动子线程的信号
private:Ui::Widget *ui;MyThread *myT;QThread *thread;
};
#endif // WIDGET_H

mythread.cpp:

#include "mythread.h"
#include <QThread>//睡觉用
MyThread::MyThread(QObject *parent) : QObject(parent)
{isStop = false;
}
void MyThread::myTimeout()
{while (isStop == false){QThread::sleep(1);emit mySignal();if(true == isStop){ break;}}
}void MyThread::setFlag(bool flag)
{isStop = flag;
}

widget.cpp:

#include "widget.h"
#include "ui_widget.h"
#include <QThread>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
//这里并不是两个线程,myT定义线程函数,thread才是子线程//动态分配空间,不能指定父对象,因为子线程是myT的父亲,如果指定父对象,那么就有两个父对象,是不对的,会报错。myT = new MyThread();//创建子线程thread = new QThread(this);//把自定义线程函数加入到子线程中myT->moveToThread(thread);connect(myT,&MyThread::mySignal,this,&Widget::dealSignal);connect(this,&Widget::startThread,myT,&MyThread::myTimeout);connect(this,&Widget::destroyed,this,&Widget::dealClose);
}void Widget::dealSignal()
{static int i = 0;i++;ui->lcdNumber->display(i);
}
Widget::~Widget()
{delete ui;
}void Widget::dealClose()
{on_pushButton_clicked();
}void Widget::on_pushButton_2_clicked()
{if(thread->isRunning() == true){return;}//启动线程,但是没有启动线程处理函数thread->start();myT->setFlag(false);//不能直接调用线程处理函数,否则导致线程处理函数和主线程在同一个线程,结果是无响应,只能通过信号和槽调用emit startThread();
}void Widget::on_pushButton_clicked()
{if(thread->isRunning() == false){return;}myT->setFlag(true);thread->quit();thread->wait();
}
  • 在线程中画图(注意:通过槽函数触发线程处理函数,通过线程处理函数触发绘图函数,谁触发谁,谁触发谁,思路很重要):

在这里插入图片描述
myThread.h:

#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QObject>
#include <QImage>class MyThread : public QObject
{Q_OBJECT
public:explicit MyThread(QObject *parent = nullptr);
//线程处理函数void drawImage();
signals:void updateImage(QImage);//函数声明形参名称可加可不加
};#endif // MYTHREAD_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QImage>
#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 paintEvent(QPaintEvent *);void getImage(QImage);//槽函数void dealClose();//窗口关闭槽函数
private:Ui::Widget *ui;QImage image;MyThread *myT;//自定义线程对象QThread *thread;//子线程
};
#endif // WIDGET_H

mythread.cpp:

#include "mythread.h"
#include <QPainter>
#include <QImage>
#include <QPen>
#include <QBrush>
MyThread::MyThread(QObject *parent) : QObject(parent)
{
}void MyThread::drawImage()
{//定义绘图设备QImage image(500,500,QImage::Format_ARGB32);//_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);//定义五个点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.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
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();//线程处理函数必须通过信号槽调用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();//回收资源
}
void Widget::getImage(QImage temp)
{image = temp;update();//更新窗口 间接调用paintEvent
}void Widget::paintEvent(QPaintEvent *)
{QPainter p(this);//创建画家,指定绘图设备为窗口p.drawImage(50,50,image);//起点坐标,图片有多大画多大
}

在这里插入图片描述

  • 多线程实例:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://chatgpt.dhexx.cn/article/kOniihGu.shtml

相关文章

Qt多线程编程

由于疫情原因被封控在家&#xff0c;相信大家也有跟我类似的情况&#xff0c;在学习知识提升和充实自己&#xff0c;下面我将这几天在学习的Qt多线程编程做个简单的总结&#xff0c;随此笔记的还有几个简单的例子&#xff0c;以便后续开发过程中回忆和参考。 Qt的多线程开发&am…

Qt多线程

Qt多线程有两种方法&#xff1a; 1、定义一个QThread的派生类&#xff0c;重写run函数&#xff0c;run函数中的程序就是新线程中要执行的内容。在主线程中实例化该类&#xff0c;调用start函数&#xff0c;就可以实现多线程。 2、定义一个QObject的派生类&#xff0c;把要在新线…

Qt创建多线程的两种方法

来源&#xff1a;https://github.com/czyt1988/czyBlog/tree/master/tech/QtThread 1.摘要 Qt有两种多线程的方法&#xff0c;其中一种是继承QThread的run函数&#xff0c;另外一种是把一个继承于QObject的类转移到一个Thread里。 Qt4.8之前都是使用继承QThread的run这种方法…

Qt----多线程

文章目录 多线程一、继承QThread的线程1. 应用实例2. 程序运行效果 二、继承QObject的线程1. 应用实例2. 程序运行效果 多线程 我们写的一个应用程序&#xff0c;应用程序跑起来后一般情况下只有一个线程&#xff0c;但是可能也有特殊情况。比如我们前面章节写的例程都跑起来后…

Qt5教程(九):Qt多线程

目录&#xff1a; 一、创建工程 二、QThread 源码一览 三、QThread相关方法介绍 四、创建线程 一、创建工程 先创建一个工程吧, 具体步骤前面讲过很多次了&#xff0c; 就不再细说了。 然后在Header文件夹下创建添加一个头文件, 右键Headers -> Add New... -> C -&g…

Qt 多线程的几种实现方式

Qt多线程的实现方式有&#xff1a; 1. 继承QThread类&#xff0c;重写run()方法 2. 使用moveToThread将一个继承QObject的子类移至线程&#xff0c;内部槽函数均在线程中执行 3. 使用QThreadPool,搭配QRunnable&#xff08;线程池&#xff09; 4. 使用QtConcurrent&#xf…

QT中的多线程

目录 1、QThread介绍 1.2、继承Qthread类 1.2.1、得到线程id 1.2.2、让线程一直执行 1.2.3、线程退出 1.2.4、​​​​​​​connect的第五个参数 1.2.5、线程锁 QMutex ​​​​​​​ 1、QThread介绍 QThread类提供了一个与平台无关的管理线程的方法。一个QThread对…

faild to create process解决办法

win7下运行pip时报faild to create process的解决办法&#xff1a; 1.找到python.exe文件&#xff0c;复制其文件路径。如下图&#xff0c;python.exe路径为D:\interpreter\python.exe。 2.找到pip-script.py文件&#xff0c;打开。将步骤1中复制的路径粘贴在第一行&#xff0…

CreateProcess error=2, 系统找不到指定的文件 解决方法

CreateProcess error2, 系统找不到指定的文件 解决方法 一般这是由于ndk缺少文件引起的 解决方法1&#xff1a; 在项目根目录下的local.properties文件中加cmd后缀 方法二下载16b的版本替换原来的ndk-bundle目录&#xff0c;默认在C:\Users\用户名\AppData\Local\Android\S…

SQL SERVER 2008 执行xp_cmdshell的过程中出错,调用createprocess失败,错误代码 5 解决方案

1、进入 控制面板----管理工具------本地安全策略 点击 本地策略--------安全选项 把“网络安全:LAN管理器身份验证级别”双击打开&#xff0c;选择“发送 LM 和 NTLM 响应”&#xff08;原来是“没有定义”&#xff09;。确认后&#xff0c;重新启动服务器&#xff0c;该问题…

runnerw.exe: CreateProcess failed with error 5:

在idea配置Git时遇到这个问题&#xff1a; 后来发现是我路径设置错了&#xff1a; 解决方案 修改设置里的路径即可&#xff08;Setings-Version Control-Git&#xff09;

Qt creater出现“启动程序失败,路径或者权限错误”或“The process could not be started!”解决方法

Qt creater出现“启动程序失败&#xff0c;路径或者权限错误”或“The process could not be started&#xff01;”解决方法 错误示例 远古版本的QTCreator在编译程序时没问题&#xff0c;在运行程序时会提示“The process could not be started&#xff01;" 较新版本…

failed to create process.

由于python-2.7是先出来&#xff0c;但是官方只更新到2020年1月1日&#xff1b;而python-3.6与python-2.7有一定的差别&#xff0c;会同时在电脑上安装这两个版本的python&#xff0c;为了能更好的调用python不同的版本&#xff0c;会设定一个执行时使用python2.exe&#xff0c…

CreateProcessAsUser

该CreateProcessAsUser函数创建一个新的进程及其主线程。新进程然后执行指定的可执行文件。该CreateProcessAsUser功能类似的CreateProcess函数&#xff0c;除了新进程运行在由hToken参数表示的用户的安全上下文中。默认情况下&#xff0c;新进程是非交互式的&#xff0c;即它运…

生成了文件却还是报错 Error:CreateProcess failed

想起来&#xff0c;以前用keil编译器的时候&#xff0c;也出现过这样的问题&#xff1a; 第一眼都是看到了“1 Error(s)”&#xff0c;就下意识认为自己程序出错了&#xff0c;找了半天没找到。 后来多看了一眼&#xff0c;发现完全这个错误其实可以完全不用理会&#xff0c;因…

【Error】Error running process: CreateProcess failed. Code 2

重新安装了pycham发现在pycharm里打不开控制台窗口了 解决办法&#xff1a; 在file -->setting --> Tools --> Terminal里 把Shell path 从 powershell.exe 改为 cmd.exe

Cannot run program “svn“ (in directory “D:xxxx“): CreateProcess error=2, 系统找不到指定的文件。报错解决方法

目录 一、报错内容 二 、原因 三、解决方法 一、报错内容 Cannot run program "svn" (in directory "xxxx"): CreateProcess error2, 系统找不到指定的文件 二 、原因 TortoiseSVN安装的时候没有安装command命令&#xff0c;不能通过命令执行版本管理…

CreateProcess error=5, 拒绝访问

一、情景再现 在一个Java项目中引入一个Python执行脚本&#xff0c;运行项目时报错&#xff1a; 二、问题分析 查看代码调用了源码中的exec&#xff08;&#xff09;方法 在java中&#xff0c;RunTime.getRuntime().exec()实现了调用服务器命令脚本来执行功能需要。也就是说…

failed to create process 的解决方式

网上大多数都是说python.exe移动了位置&#xff0c;导致你本来环境变量中配置的scripts中的python.exe找不到位置。 你需要修改scripts中的pip.exe中的python路径 如 当然这是其中一种可能性&#xff0c; 也有可能是由于你自己配置的环境变量产生了冲突 在windows的系统环境…

CreateProcess 创建进程失败原因调查

使用 CreateProcess 函数创建进程&#xff08;调用外部程序&#xff09;算是很常用的操作了&#xff0c;最近在工作中却遇到一个少见的怪现象&#xff0c;经常使用的一段代码&#xff08;调用外部程序并等待其结束&#xff0c;主要就使用了 CreateProcess 函数&#xff09;&…