【C++】-QT多线程-006

发布于:2024-05-07 ⋅ 阅读:(27) ⋅ 点赞:(0)

1【QT】多线程

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>

namespace Ui {
class MyWidget;
}

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    explicit MyWidget(QWidget *parent = 0);
    ~MyWidget();

/* 5 自定义信号*/
/*所有的信号函数只声明不定义!*/
signals:
    void notify();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MyWidget *ui;

    QThread *pThread;//添加线程成员-
};

#endif // MYWIDGET_H



#ifndef WORKER_H
#define WORKER_H

#include <QObject>

/* 2 创建派生类-这里创建一个子线程类*/
class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr);

signals:


public slots:
    /* 7 写子线程类的槽函数*/
    void onNotify();

private:
    /*2.1添加新成员-*/
    void doSomeThing();
};

#endif // WORKER_H





#include "MyWidget.h"
#include <QApplication>

/* 1 添加组件*/

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyWidget w;
    w.show();

    return a.exec();
}




#include "MyWidget.h"
#include "ui_MyWidget.h"

#include <QThread>
#include "Worker.h"


MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);

/* 3 在主线程中添加子线程*/
    /* 3.1 创建子线程空间*/
//    QThread *pThread=new QThread(this);
    pThread=new QThread(this);//优化
    /* 3.2 创建子线程类*/
    Worker *p=new Worker;
    /* 3.3 将子线程类移动到子线程空间*/
    p->moveToThread(pThread);

    /* 9 子线程优化-子线程结束之前销毁子线程空间中的成员*/
    /*子线程-子线程结束-子线程空间中的成员(这里是1个类)-销毁成员*/
    connect(pThread,&QThread::finished,p,&Worker::deleteLater);

    /*建立主线程中的信号与子线程中槽的连接*/
    connect(this,&MyWidget::notify,p,&Worker::onNotify);

/* 4 启动子线程*/
    pThread->start();
}

MyWidget::~MyWidget()
{
    /* 10 主动结束子线程-在主线程结束之前,先等待子线程执行结束*/
    pThread->quit();//退出线程
    pThread->wait();//等待线程结束

    delete ui;
}

/* 6 写按钮的槽函数*/
void MyWidget::on_pushButton_clicked()
{
    /* 7.1 向子线程中的槽发送信号*/
    emit notify();
}




#include "Worker.h"
#include <QThread>
#include <QDebug>
/*包含头文件->调用类*/



Worker::Worker(QObject *parent) : QObject(parent)
{

}

/* 7 写子线程槽函数*/
/*子线程中的槽-需要与主线程中的信号建立连接/通信-
 * 主线程中的按钮按下,向子线程中的槽发送信号*/
void Worker::onNotify()
{
    /*调用任务函数-流程梳理: 主线程中的信号【notify】->发送信号(主线程的某个成员对象向子线程中的槽)
->接收信号-槽(子线程中的成员对象接收来自主线程成员对象的信号)->执行线程任务(在子线程槽函数中调用任务处理函数)*/
    doSomeThing();/* 7.2 子线程中的槽执行任务*/
}


/* 7.3 写任务函数*/
void Worker::doSomeThing()
{
    for(int i=0;i<10;++i)
    {
        QThread::sleep(1);

        /* 8 添加调试方法-可以观察到子线程任务是否执行*/
        qDebug()<<i;
    }
}

这里特别需要注意一种【ui】调试方法:【qdebug】调试

2【QT】进度条

用于描述程序执行状态

2.1利用行编辑器显示子线程执行状态

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>

namespace Ui {
class MyWidget;
}

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    explicit MyWidget(QWidget *parent = 0);
    ~MyWidget();

/* 5 自定义信号*/
/*所有的信号函数只声明不定义!*/
signals:
    void notify();

private slots:
    void on_pushButton_clicked();

    /* 11.3 定义进度条槽函数*/
    void onFn(int n);

private:
    Ui::MyWidget *ui;

    QThread *pThread;//添加线程成员-
};

#endif // MYWIDGET_H





#ifndef WORKER_H
#define WORKER_H

#include <QObject>

/* 2 创建派生类-这里创建一个子线程类*/
class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr);

signals:
    /* 11.1 自定义进度条信号*/
    void fn(int n);

public slots:
    /* 7 写子线程类的槽函数*/
    void onNotify();

private:
    /*2.1添加新成员-*/
    void doSomeThing();
};

#endif // WORKER_H




#include "MyWidget.h"
#include <QApplication>

/* 1 添加组件*/

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyWidget w;
    w.show();

    return a.exec();
}





#include "MyWidget.h"
#include "ui_MyWidget.h"

#include <QThread>
#include "Worker.h"


MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);

/* 3 在主线程中添加子线程*/
    /* 3.1 创建子线程空间*/
//    QThread *pThread=new QThread(this);
    pThread=new QThread(this);//优化
    /* 3.2 创建子线程类*/
    Worker *p=new Worker;
    /* 3.3 将子线程类移动到子线程空间*/
    p->moveToThread(pThread);

    /* 9 子线程优化-子线程结束之前销毁子线程空间中的成员*/
    /*子线程-子线程结束-子线程空间中的成员(这里是1个类)-销毁成员*/
    connect(pThread,&QThread::finished,p,&Worker::deleteLater);

    /*建立主线程中的信号与子线程中槽的连接*/
    connect(this,&MyWidget::notify,p,&Worker::onNotify);

    /* 11.4 建立进度条的信号与槽的连接*/
    connect(p,&Worker::fn,this,&MyWidget::onFn);

    /* 4 启动子线程*/
    pThread->start();
}

MyWidget::~MyWidget()
{
    /* 10 主动结束子线程-在主线程结束之前,先等待子线程执行结束*/
    pThread->quit();//退出线程
    pThread->wait();//等待线程结束

    delete ui;
}

/* 6 写按钮的槽函数*/
void MyWidget::on_pushButton_clicked()
{
    /* 7.1 向子线程中的槽发送信号*/
    emit notify();
}

/*进度条槽函数*/
void MyWidget::onFn(int n)
{
    /*将进度条接收到的信号信息显示在行编辑器中(界面)*/
    ui->lineEdit->setText(QString::asprintf("%d",n));
}




#include "Worker.h"
#include <QThread>
#include <QDebug>
/*包含头文件->调用类*/



Worker::Worker(QObject *parent) : QObject(parent)
{

}

/* 7 写子线程槽函数*/
/*子线程中的槽-需要与主线程中的信号建立连接/通信-
 * 主线程中的按钮按下,向子线程中的槽发送信号*/
void Worker::onNotify()
{
    /*调用任务函数-流程梳理: 主线程中的信号【notify】->发送信号(主线程的某个成员对象向子线程中的槽)
->接收信号-槽(子线程中的成员对象接收来自主线程成员对象的信号)->执行线程任务(在子线程槽函数中调用任务处理函数)*/
    doSomeThing();/* 7.2 子线程中的槽执行任务*/
}


/* 7.3 写任务函数*/
void Worker::doSomeThing()
{
    for(int i=0;i<10;++i)
    {
        QThread::sleep(1);
#if 0
        /* 8 添加调试方法-可以观察到子线程任务是否执行*/
        qDebug()<<i;
#endif

#if 1
        /* 11.2 发送进度条信号*/
        emit fn(i);
#endif
    }
}

2.2利用进度条显示子线程执行状态

实现方法:在进度条槽函数中添加set方法,使得进度条当前值与槽函数接收到的信号值同步,就实现了进度条动态增长。
/*进度条槽函数*/
void MyWidget::onFn(int n)
{
    /*将进度条接收到的信号信息显示在行编辑器中(界面)*/
    ui->lineEdit->setText(QString::asprintf("%d",n));

    /*同时将信号传给槽的信号信息n,用于设置进度条的当前值*/
    ui->progressBar->setValue(n);
}