如何使用QT5实现多线程(一)

时间:2024-03-08 10:15:50

情景模拟

假如我们要统计一个函数的运行时间我们可以用什么方法呢?掐秒表的那位同学请坐下(划掉)

很显然我们可以通过开辟线程的办法,函数在一个线程内跑,计时函数在另外一个线程内跑.我们便可以在函数运行的时候统计运行时间(虽然运用某些计时函数能更加准确)

下面就来实现这一构思

多线程的优点

1.提高应用程序的响应时间.这对于开发图形界面的程序尤其重要,当一个操作耗时很长的时候,整个系统都会等待这个操作,程序就不能响应键盘鼠标等的操作,而多线程可以将耗时长的操作置于一个新的线程上,避免以上问题

2.使多CPU系统更加有效.当线程数不多于CPU数目时,不同的线程可以在不同的CPU上运行

3改善程序结构.一个既长又复杂的进程可以分为多个线程,成为独立的运行部分,这样有利于代码的理解和维护

具体实现

1.先创建一个带ui的程序

其中的按钮按下则开始启动线程,同时启动计时

2.添加一个基类为QThread的.h和.cpp文件

#ifndef THREAD_ONE_H
#define THREAD_ONE_H

#include <QThread>

class thread_one : public QThread
{
    Q_OBJECT
public:
    explicit thread_one(QObject *parent = nullptr);
protected:
    void run();//多线程执行的内容将通过重新该虚函数实现
signals:
    void over();
public slots:
};

#endif // THREAD_ONE_H
#include "thread_one.h"

thread_one::thread_one(QObject *parent) : QThread(parent)
{
}
void thread_one::run()
{
    sleep(5);//模拟一个时长5s的复杂函数
    emit over();//复杂函数结束后发出信号
}

3.在主线程的文件中设置计时器

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QTimer>
#include"thread_one.h"
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();
    void dealclicked();
    void dealtimeout();
private slots:
    void dealover();//处理新线程返回的结束信号

private:
    Ui::Widget *ui;
    QTimer *timer;
    thread_one *thread;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    //初始化
    ui->setupUi(this);
    timer = new QTimer(this);
    thread = new thread_one(this);
    
    
    connect(ui->pushButton,&QPushButton::clicked,this,&Widget::dealclicked);//按下按钮后执行dealclicked()槽函数
    
    
    connect(timer,&QTimer::timeout,this,&Widget::dealtimeout);//根据定时器发出的信号更新LCD显示器的数字
    connect(thread,&thread_one::over,this,&Widget::dealover);//当开辟的线程内的复杂函数执行完后,发出over信号,接收到该信号后便停下计时器
}

Widget::~Widget()
{
    delete ui;
}

void Widget::dealclicked()
{
    timer->start(100);//启动计时器,每0.1秒发出一次信号
    thread->start();//QThread 的对象通过start()函数调用线程文件中的run()函数
}
void Widget::dealtimeout()//更新LCD显示器的数字
{
    static int time = 0;
    ui->lcdNumber->display(time);
    time++;
}
void Widget::dealover()//接收到信号后停下计时器
{
    timer->stop();
}

上述内容参考<<Qt5开发及实例>>