totosugito
6th February 2015, 04:40
Hi,
I am create a simple window like attached image.
10942
The algorithm is like this. When user move the scrollbar, the program will create a thread using scrollbar index as the ID.
I am try to create worker class as an object like below :
worker.h
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include <QMutex>
class workerThread;
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0);
void requestWork(int id);
void abort();
void run();
void runThread(int id);
private:
bool _abort;
bool _working;
QMutex mutex;
int ID;
bool prepareThread(workerThread *&thread);
workerThread *thisThread;
signals:
void workRequested();
void valueChanged(const QString &value);
void finished();
public slots:
void doWork();
void thisThreadStarted();
void thisThreadFinished();
};
#include <QThread>
class workerThread : public QThread
{
Q_OBJECT
public:
workerThread(Worker *workerThr):workerThr(workerThr){}
virtual ~workerThread(){}
void run() {workerThr->run();}
protected:
Worker *workerThr;
};
#endif // WORKER_H
worker.cpp
#include "worker.h"
#include <QTimer>
#include <QEventLoop>
#include <QThread>
#include <QDebug>
Worker::Worker(QObject *parent) :
QObject(parent)
{
_working =false;
_abort = false;
thisThread = NULL;
}
void Worker::abort()
{
mutex.lock();
if (_working)
{
_abort = true;
//qDebug()<<"Abort "<<QString::number(ID);
}
mutex.unlock();
}
void Worker::run()
{
doWork();
}
void Worker::runThread(int id)
{
//abort thread
abort();
//check if thread still run
//check thread every 10ms
while(thisThread)
{
QEventLoop loop;
QTimer::singleShot(10, &loop, SLOT(quit()));
loop.exec();
}
mutex.lock();
_working = true;
_abort = false;
ID = id;
mutex.unlock();
//run the new thread
thisThread = NULL;
prepareThread(thisThread);
thisThread->start();
}
void Worker::doWork()
{
qDebug()<<"Process "<<QString::number(ID);
for (int i = 0; i < 10; i ++)
{
// Checks if the process should be aborted
mutex.lock();
bool abort = _abort;
mutex.unlock();
if (abort)
{
qDebug()<<"Aborting "<<QString::number(ID);
break;
}
else
{
// add very heavy process
QEventLoop loop;
QTimer::singleShot(200, &loop, SLOT(quit()));
loop.exec();
}
}
// Set _working to false, meaning the process can't be aborted anymore.
mutex.lock();
_working = false;
mutex.unlock();
qDebug()<<"Finished "<<QString::number(ID);
emit finished();
}
bool Worker::prepareThread(workerThread *&thread)
{
thread = new workerThread(this);
connect(thread, SIGNAL(started()), this,
SLOT(thisThreadStarted()), Qt::BlockingQueuedConnection);
connect(thread, SIGNAL(finished()), this,
SLOT(thisThreadFinished()), Qt::BlockingQueuedConnection);
connect(thread, SIGNAL(terminated()), this,
SLOT(thisThreadFinished()), Qt::BlockingQueuedConnection);
return true;
}
void Worker::thisThreadStarted()
{
}
void Worker::thisThreadFinished()
{
thisThread = NULL;
}
But, I get the problem. When I move the scroolbar to another index (from 1 to 314). I hope the program process the last 314th index when I dont move scrollbar again. But, I get the debug message the program still process the previous index.
Aborting "8"
Finished "8"
Process "314"
Finished "314" <--- I hope the program stop in here and not process the previous ID
Process "311"
Finished "311"
Process "309"
Finished "309"
Process "307"
Finished "307"
Process "304"
Finished "304"
Please help me how to solve this problem.
I have attached my full code.
Thank you for your attention.
best regards,
totosugito
I am create a simple window like attached image.
10942
The algorithm is like this. When user move the scrollbar, the program will create a thread using scrollbar index as the ID.
I am try to create worker class as an object like below :
worker.h
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include <QMutex>
class workerThread;
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0);
void requestWork(int id);
void abort();
void run();
void runThread(int id);
private:
bool _abort;
bool _working;
QMutex mutex;
int ID;
bool prepareThread(workerThread *&thread);
workerThread *thisThread;
signals:
void workRequested();
void valueChanged(const QString &value);
void finished();
public slots:
void doWork();
void thisThreadStarted();
void thisThreadFinished();
};
#include <QThread>
class workerThread : public QThread
{
Q_OBJECT
public:
workerThread(Worker *workerThr):workerThr(workerThr){}
virtual ~workerThread(){}
void run() {workerThr->run();}
protected:
Worker *workerThr;
};
#endif // WORKER_H
worker.cpp
#include "worker.h"
#include <QTimer>
#include <QEventLoop>
#include <QThread>
#include <QDebug>
Worker::Worker(QObject *parent) :
QObject(parent)
{
_working =false;
_abort = false;
thisThread = NULL;
}
void Worker::abort()
{
mutex.lock();
if (_working)
{
_abort = true;
//qDebug()<<"Abort "<<QString::number(ID);
}
mutex.unlock();
}
void Worker::run()
{
doWork();
}
void Worker::runThread(int id)
{
//abort thread
abort();
//check if thread still run
//check thread every 10ms
while(thisThread)
{
QEventLoop loop;
QTimer::singleShot(10, &loop, SLOT(quit()));
loop.exec();
}
mutex.lock();
_working = true;
_abort = false;
ID = id;
mutex.unlock();
//run the new thread
thisThread = NULL;
prepareThread(thisThread);
thisThread->start();
}
void Worker::doWork()
{
qDebug()<<"Process "<<QString::number(ID);
for (int i = 0; i < 10; i ++)
{
// Checks if the process should be aborted
mutex.lock();
bool abort = _abort;
mutex.unlock();
if (abort)
{
qDebug()<<"Aborting "<<QString::number(ID);
break;
}
else
{
// add very heavy process
QEventLoop loop;
QTimer::singleShot(200, &loop, SLOT(quit()));
loop.exec();
}
}
// Set _working to false, meaning the process can't be aborted anymore.
mutex.lock();
_working = false;
mutex.unlock();
qDebug()<<"Finished "<<QString::number(ID);
emit finished();
}
bool Worker::prepareThread(workerThread *&thread)
{
thread = new workerThread(this);
connect(thread, SIGNAL(started()), this,
SLOT(thisThreadStarted()), Qt::BlockingQueuedConnection);
connect(thread, SIGNAL(finished()), this,
SLOT(thisThreadFinished()), Qt::BlockingQueuedConnection);
connect(thread, SIGNAL(terminated()), this,
SLOT(thisThreadFinished()), Qt::BlockingQueuedConnection);
return true;
}
void Worker::thisThreadStarted()
{
}
void Worker::thisThreadFinished()
{
thisThread = NULL;
}
But, I get the problem. When I move the scroolbar to another index (from 1 to 314). I hope the program process the last 314th index when I dont move scrollbar again. But, I get the debug message the program still process the previous index.
Aborting "8"
Finished "8"
Process "314"
Finished "314" <--- I hope the program stop in here and not process the previous ID
Process "311"
Finished "311"
Process "309"
Finished "309"
Process "307"
Finished "307"
Process "304"
Finished "304"
Please help me how to solve this problem.
I have attached my full code.
Thank you for your attention.
best regards,
totosugito