qt线程异步(解决耗时任务界面卡死)12345

cgy33 / 2023-06-17 / 原文

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QItemDelegate>
#include <QModelIndex>
#include <QStringListModel>
#include <QListView>
#include <QToolButton>
#include <QMouseEvent>
#include <QStackedLayout>
#include <QTextEdit>
#include <QThread>
#include <QListWidgetItem>
#include <QDebug>
#include <string>
#include <iostream>
#include <algorithm>
#include <QTimer>
#include <QElapsedTimer>
#include <QtConcurrent>
#include <QRunnable>
//qt定时器里面做耗时操作界面卡死
//耗时操作与并发(线程异步)
//1、GUI线程,就是主线程,也就是界面
//2、使用定时器
//3、工作线程,也就是处理耗时操作的线程,耗时操作都放在工作线程,不然界面会卡死

//1、QT并发,QtConCurrent,QT += concurrent
//2、任务Runnable与线程池Threadpool
//3、线程Thread
//4、QcoreApplication::processEvents
//5、qt事件循环就是一个事件的循环,鼠标按下,界面拖动,qpainter画图就是事件循环,局部事件循环就是最简单的同步机制阻塞QEventLoop.exec之前的函数调用
int Operation()
{
    //耗时操作函数
    int time = 1;
    while(time)
    {
        //QCoreApplication::processEvents();//动界面时,不进行耗时操作,不动界面时开始耗时操作,加在耗时操作的循环内
         qDebug()<<__func__<<time;
         if(time == 0xffff)
         {
             qDebug()<<"耗时操作结束@@@";
             time = 0;
             break;
         }
         time++;
    }
    return 999;
}

class Thread: public QThread
{
public:
    Thread()
    {

    }
   // QThread interface
protected:
    void run()
    {
       Operation();
    }

};


class Thread2:public QObject
{
    //Q_OBJECT
public:
    Thread2() = default;
    void fun()
    {
        Operation();
    }
};

class Thread3 :public QRunnable
{
    // QRunnable interface
public:
    void run()
    {
        Operation();
    }
};
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    ui->setupUi(this);
    timer = new QTimer(this);
    timer->setInterval(2000);
    connect(timer,&QTimer::timeout,this,&MainWindow::SlotTimerOut);
    timer->start();


}

MainWindow::~MainWindow()
{
    timer->stop();
    delete ui;
}

int MainWindow::ClassOperation(int a,int b,int c,int d,int e)
{
    qDebug()<<a<<b<<c<<d<<e;
  return  Operation();
}

void MainWindow::SlotTimerOut()
{
    static int time;
    qDebug()<<"==========================================="<<time;
    //Thread *t = new Thread();
    //t->start();

    //Thread2 *t2 = new Thread2();
    //QThread *t3 = new QThread();
    //t2->moveToThread(t3);
    //connect(t3,&QThread::started,t2,&Thread2::fun);
    //t3->start();

    //Qt并发
    //并发是更高层的接口,可以不去操作底层的线程,也不需要关心信号和槽所在的线程,比较容易上手。Qt Concurrent使用方法很简单,如果是普通函数,调用方式为:
    //QFuture<T> QtConcurrent::run(Function function, ... )
    //如果是类的成员函数,需要传入对象指针。比如上面的例子,相当于默认传入了一个全局指针:
    //QtConcurrent::run(QThreadPool::globalInstance(), function, ...);
    //QT += concurrent
   //QFuture<int> future =  QtConcurrent::run(this,&MainWindow::ClassOperation,1,2,3,4,5);//最多可以传五个参数
   //while(!future.isFinished())
   //{
   //    qDebug()<<"还未完成...........................";
   //    QCoreApplication::processEvents();
   //}
   //  qDebug()<<"期物的结果是"<<future.result();//期物的结果就是函数的返回值就是

    //Thread3 *t3 = new Thread3();
    //t3->setAutoDelete(true);
    //QThreadPool::globalInstance()->setMaxThreadCount(1);
    //QThreadPool::globalInstance()->start(t3);

    QEventLoop eveloop;
    Operation();
    eveloop.exec();
    eveloop.wakeUp();
    time++;
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QAbstractButton>
#include <QLabel>
#include <QMainWindow>
#include <QPen>
#include <QStackedLayout>
#include <QToolButton>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    int ClassOperation(int a, int b, int c, int d, int e);//类的耗时操作,使用QtConCurrent,Q并发类
public slots:
    void SlotTimerOut();
signals:
    void threadSignal();
private:
    Ui::MainWindow *ui;
    QTimer *timer;
};

#endif // MAINWINDOW_H