开发过程中,一些运算耗时比较长的任务,我们会将其放在线程中运行。
任务前提
从网络上传来了大量的图片,我们短时间内会接收很多,但是处理图片的时间比接受时间长的多。
处理步骤
1.首先我们创建一个任务管理类,用于管理任务的信息
task.h
#ifndef TASK_H
#define TASK_H
#include <QImage>
/*
* 用于管理任务的所有信息
* 也可以内部处理
*/
class Task
{
public:
Task(QImage image,QString path);
bool saveImage();
QString path();
private:
QImage m_image;//将要保存的图片
QString m_strSavePath;//保存
};
#endif // TASK_H
task.cpp
#include "task.h"
#include <QDebug>
Task::Task(QImage image,QString path)
: m_image(image)
, m_strSavePath(path)
{
}
bool Task::saveImage()
{
bool ret = true;
// if(!m_image.isNull()&& !m_strSavePath.isEmpty()){
// ret = m_image.save(m_strSavePath);
// }
qDebug()<<"执行完毕";
return ret;
}
QString Task::path(){
return m_strSavePath;
}
2.创建线程,用于添加任务并处理
workThread.h
#ifndef WORKTHREAD_H
#define WORKTHREAD_H
#include <QThread>
#include <QMutex>
//线程任务队列
class Task;
class workThread : public QThread
{
Q_OBJECT
public:
workThread(QObject *parent = 0);
void run();
void addTask(Task *task); //添加任务在最前面,最后添加的优先级最高
void stop(){ m_bStart = false;}
Task *popTask();
signals:
void sigWorkfinish(QString);
private:
QList<Task *>m_taskList;// 任务列表
QMutex m_mutex;
bool m_bStart = true;
};
#endif // WORKTHREAD_H
workthread.cpp
/*
*@brief:循环执行任务的线程队列
* @author:swang
*/
#include "workthread.h"
#include "task.h"
workThread::workThread(QObject * parent)
:QThread(parent)
,m_bStart(true)
{
}
void workThread::run()
{
while (m_bStart) {
Task * task = popTask();
if(task){
if(task->saveImage()){
emit sigWorkfinish(task->path());
delete task;
task = nullptr;
}
}
msleep(1000);
}
}
//新增任务,可以采用头插法或者尾插法,注意加锁
void workThread::addTask(Task *task)
{
m_mutex.lock();
m_taskList.push_front(task);//头插
//m_taskList.push_back(task);//尾插
m_mutex.unlock();
}
//取出任务,每次取链表的第一个值
Task *workThread::popTask()
{
m_mutex.lock();
Task *task;
if(0 == m_taskList.size())
{
task = nullptr;
}
else
{
task = m_taskList.takeFirst();
}
m_mutex.unlock();
return task;
}
在这里,我们创建了一个线程,采用头插法,将任务插入任务list中,注意取出任务时也是取得头元素
m_taskList.push_front(task);
3.调用
MainWindow.cpp
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, pworkThread(new workThread(this))
{
ui->setupUi(this);
pworkThread->start();
QImage image;
for(int i = 0; i< 100; i++)
{
pworkThread->addTask(new Task(image,"ss"));
}
connect(pworkThread,&workThread::sigWorkfinish,[=](QString s){
qDebug()<<s;
});
}
MainWindow::~MainWindow()
{
pworkThread->stop();
pworkThread->quit();
pworkThread->wait();
delete ui;
}
源码