• 注意

    线程里面尽量少用 while(1) + sleep(),尤其是while

    eg:第一个例子如果用while(1),那么当线程exit(),并等待退出时wait()时不会退出线程,等待超时后会报错

    QThread介绍

    QThread类提供了一个与平台无关的管理线程的方法。一个QThread对象管理一个线程。QThread的执行从run()函数的执行开始,在Qt自带的QThread类中,run()函数通过调用exec()函数来启动事件循环机制,并且在线程内部处理Qt的事件。在Qt中建立线程的主要目的就是为了用线程来处理那些耗时的后台操作,从而让主界面能及时响应用户的请求操作。QThread的使用方法有如下两种:

    继承QThread类

    Qt多线程编程-LMLPHP程序运行后开启线程,打印100~0

    Program右键添加新文件,继承QThread

    添加头文件

    #include <QObject>
    #include <QThread>

    添加宏

    不添加Q_OBJECT宏无法使用信号与槽机制

    Q_OBJECT

    重写run函数

    protected:
    virtual void run();

    mythread.h文件:

    #ifndef MYTHREAD_H
    #define MYTHREAD_H
    #include <QObject>
    #include <QThread>

    class MyThread : public QThread
    {
    Q_OBJECT
    public:
    MyThread();
    protected:
    virtual void run();
    private:
    };
    #endif // MYTHREAD_H

    mythread.cpp

    #include "mythread.h"
    #include <QtDebug>
    MyThread::MyThread()
    {
    /*MyThread的构造函数任然在主线程里面*/
    qDebug()<<"MyThread::MyThread:"<<QThread::currentThreadId();
    }

    void MyThread::run()
    {
    while(1)
    {
    qDebug()<<"MyThread::run:"<<QThread::currentThreadId();
    QThread::sleep(1);
    }
    }

    main.c

    #include <QCoreApplication>
    #include <QThread>
    #include <QDebug>
    #include "mythread.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);

    qDebug()<<"main a.exec() :"<<QThread::currentThreadId();
    MyThread thread1;
    thread1.start();
    /*使用线程只需要再次定义线程类MyThread即可*/
    // MyThread thread2;
    // thread2.start();
    return a.exec();
    }

    这里有一个小示例

    创建的是带界面的mainwindow窗口

    Program右键添加新文件,继承QObject

    MyThread.h

    #ifndef MYTHREAD_H
    #define MYTHREAD_H
    #include <QObject>
    class MyThread : public QObject
    {
    Q_OBJECT
    public:
    explicit MyThread(QObject *parent = nullptr);

    signals:
    //线程向外部发出带Val值得信号
    void SendVal(int);
    public slots:
    //线程工作函数
    void MyThreadWork();
    };

    #endif // MYTHREAD_H

    MyThread.cpp

    #include "mythread.h"
    #include <QDebug>
    #include <QThread>
    MyThread::MyThread(QObject *parent) : QObject(parent){
    }
    void MyThread::MyThreadWork()
    {
    for(int val=0;val<=100;val++)
    {
    //向外部发送信号
    emit SendVal(val);
    //睡眠一秒
    QThread::sleep(1);
    qDebug()<<val;
    }
    }

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QThread>
    #include "mythread.h"

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    signals:
    void checkMyThread();
    private slots:
    void RecvVal(int Val);
    void on_pushButton_clicked();

    private:
    Ui::MainWindow *ui;
    QThread m_thread;
    MyThread m_ProgressBarVal;
    };

    #endif // MAINWINDOW_H

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    ui->progressBar->setMaximum(100); //设置进度条最大值
    ui->progressBar->setValue(0); //设置进度条当前值为0
    ui->statusBar->addWidget(ui->progressBar); //将进度条添加进状态栏MainToolBal

    m_ProgressBarVal.moveToThread(&m_thread); //m_ProgressBarVal移动到线程中去
    m_thread.start();//开启线程
    //关联信号,当触发checkMyThread()信号时执行MyThreadWork()函数
    connect(this,SIGNAL(checkMyThread()),&m_ProgressBarVal,SLOT(MyThreadWork()));
    //关联信号,当触发SendVal()信号时执行RecvVal()函数,并将值传递过去
    connect(&m_ProgressBarVal,SIGNAL(SendVal(int)),this,SLOT(RecvVal(int)));
    }

    MainWindow::~MainWindow()
    {
    //线程退出并等待10s
    m_thread.exit();
    m_thread.wait(1000*10);
    delete ui;
    }
    void MainWindow::RecvVal(int Val)
    {
    //设置进度条的值
    ui->progressBar->setValue(Val);
    }

    void MainWindow::on_pushButton_clicked()
    {
    //触发checkMyThread()信号,使MyThreadWork()工作
    emit checkMyThread();
    }


    End



    本文分享自微信公众号 - 编程学习基地(LearnBase)。
    如有侵权,请联系 [email protected] 删除。
    本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

    09-08 08:29