目录
一.介绍
二.第一种多线程方式
1.创建一个线程子类,继承QT中的QThread
2.重新父类的run( )方法
3.在线程中创建子线程对象
4.run( )方法
5.启动子线程
三.第二种多线程方式
1.创建一个新类(这个类是QObject的派生)
2.在这个类中添加一个公共成员函数
3.主线程中创建一个QThread对象(子线程对象)
4.主线程中创建工作的类对象
5.将工作的类移动到子线程中,启动子线程
6.让工作的对象开始工作
7.工作函数
四.效果演示
五.代码演示
第一种线程方法
第二种线程方法
六.总结
一.介绍
QT中的线程用于实现多任务并发执行,提高程序的执行效率和响应速度。
在QT中,线程是进行运算调度的最小单位,它们包含在进程之中并作为进程中的实际运作单位。使用线程的主要目的是让程序能够同时执行多个任务。以下是QT线程的主要作用和使用方式:
- 提高性能和响应速度:通过将耗时的操作放在单独的线程中执行,可以避免UI冻结,提高应用程序的响应速度。
- 实现多任务处理:一个进程中可以并发运行多个线程,每条线程并行执行不同的任务,有效地利用了计算机多核处理器的能力。
- 简化复杂操作:对于需要长时间运行或复杂的计算,使用线程可以使主线程保持不被阻塞,从而不影响用户界面的交互性。
- 跨平台支持:QT提供的线程类如QThread、QThreadStorage等,都是跨平台的,可以在不同操作系统中使用。
- 提供线程安全的通信机制:QT支持线程安全的事件投递、跨线程的信号-槽连接,使得不同线程间的通信变得安全高效。
QT通过提供一系列与线程相关的类和方法,使得在应用程序中创建和管理线程变得相对简单。这包括继承QThread类并重写其run()方法来定义线程的行为,以及使用Qt的信号和槽机制来处理线程间通信。
二.第一种多线程方式
1.创建一个线程子类,继承QT中的QThread
2.重新父类的run( )方法
3.在线程中创建子线程对象
4.run( )方法
5.启动子线程
三.第二种多线程方式
1.创建一个新类(这个类是QObject的派生)
2.在这个类中添加一个公共成员函数
.
3.主线程中创建一个QThread对象(子线程对象)
4.主线程中创建工作的类对象
5.将工作的类移动到子线程中,启动子线程
6.让工作的对象开始工作
7.工作函数
四.效果演示
五.代码演示
第一种线程方法
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QObject>
#include <QDebug>
#include <QVector>
#include <QThread>class MyThread : public QThread
{Q_OBJECT
public:explicit MyThread(QObject *parent = nullptr);protected:void run();signals://自定义信号,传递数据void curNumber(int num);public slots:private:};#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
#include <QDebug>MyThread::MyThread(QObject *parent) : QThread(parent)
{}void MyThread::run()
{qDebug() << "当前线程对象的地址: " << QThread::currentThread();int num = 0;while(1){emit curNumber(num++);if(num == 10000000){break;}QThread::usleep(1);}qDebug() << "run() 执行完毕, 子线程退出...";
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mythread.h"
#include <QDebug>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);qDebug()<<"主线程对象地址"<<QThread::currentThread();//创建子线程MyThread* subThread = new MyThread;connect(subThread,&MyThread::curNumber,this,[=](int num){ui->label->setNum(num);});connect(ui->startBtn, &QPushButton::clicked, this, [=](){// 启动子线程subThread->start();});}MainWindow::~MainWindow()
{delete ui;
}
第二种线程方法
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QObject>
#include <QDebug>class MyThread : public QObject
{Q_OBJECT
public:explicit MyThread(QObject *parent = nullptr);void working();signals://自定义信号,传递数据void curNumber(int num);public slots:private:};#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
#include <QDebug>
#include <QThread>MyThread::MyThread(QObject *parent) : QObject(parent)
{}void MyThread::working()
{qDebug() << "当前线程对象的地址: " << QThread::currentThread();int num = 0;while(1){emit curNumber(num++);if(num == 10000000){break;}QThread::usleep(1);}qDebug() << "run() 执行完毕, 子线程退出...";
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mythread.h"
#include <QDebug>
#include <QThread>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);qDebug()<<"主线程对象地址"<<QThread::currentThread();//创建线程对象QThread* sub = new QThread;//创建工作类对象//千万不要指定给创建的对象指定父对象//如果指定了: QObject::moveToThread: Cannot move objects with a parentMyThread* work = new MyThread;// 将工作的类对象移动到创建的子线程对象中work->moveToThread(sub);//启动线程sub->start();// 让工作的对象开始工作, 点击开始按钮, 开始工作connect(ui->startBtn, &QPushButton::clicked, work, &MyThread::working);//显示数据connect(work,&MyThread::curNumber,this,[=](int num){ui->label->setNum(num);});}MainWindow::~MainWindow()
{delete ui;
}
六.总结
继承QThread的方法只有重写run函数里的内容在子线程里运行,其他部分比如定时器的槽函数在主线程里运行。
MoveToThread的方法,所有的槽函数都在子线程里运行。