#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