ObiWanKenobe
20th October 2013, 10:32
Hi,
I'm experimenting with threads.
My goal is to write a program, which exports data from a DB to XML.
I'm planing to create 2 or 3 worker threads, that does the job.
When a thread is finished with a DB table, a new table must be assigned to the thread.
So I have to know which thread object is finished.
I wrote the following thread class for testing:
#ifndef KCOUNTERTHREAD_H
#define KCOUNTERTHREAD_H
#include <QThread>
class KCounterThread : public QThread
{
Q_OBJECT
public:
explicit KCounterThread(int id, QObject *parent = 0, int maxValue = 100, int waitTime = 100);
void run();
int maxValue() const;
void setMaxValue(int value);
int waitTime() const;
void setWaitTime(int value);
int id() const;
signals:
void counterChanged(int value);
void threadFinished(KCounterThread*);
private:
int m_maxValue;
int m_waitTime;
int m_id;
};
#endif // KCOUNTERTHREAD_H
#include "kcounterthread.h"
KCounterThread::KCounterThread(int id, QObject *parent, int maxValue, int waitTime)
: QThread(parent), m_id(id), m_maxValue(maxValue), m_waitTime(waitTime)
{
}
void KCounterThread::run()
{
for (int n = 0; n < m_maxValue; n++)
{
emit counterChanged(n);
msleep(m_waitTime);
}
emit threadFinished(this);
}
int KCounterThread::maxValue() const
{
return m_maxValue;
}
void KCounterThread::setMaxValue(int value)
{
if (!isRunning())
m_maxValue = value;
}
int KCounterThread::waitTime() const
{
return m_waitTime;
}
void KCounterThread::setWaitTime(int value)
{
if (!isRunning())
m_waitTime = value;
}
int KCounterThread::id() const
{
return m_id;
}
As you can see I emit a self declared signal threadFinished(this) at the end of the run() method.
My test program looks like this:
void MainWindow::on_pushButton2_clicked()
{
counterThread1 = new KCounterThread(1, this, 500, 10);
counterThread2 = new KCounterThread(2, this, 500, 5);
ui->progressBar1->setMaximum(counterThread1->maxValue() - 1);
ui->progressBar2->setMaximum(counterThread2->maxValue() - 1);
ui->progressBar1->setValue(0);
ui->progressBar2->setValue(0);
connect(counterThread1, SIGNAL(counterChanged(int)), this, SLOT(counter1Changed(int)));
connect(counterThread2, SIGNAL(counterChanged(int)), this, SLOT(counter2Changed(int)));
connect(counterThread1, SIGNAL(finished()), this, SLOT(counter1Finished()));
connect(counterThread2, SIGNAL(finished()), this, SLOT(counter2Finished()));
connect(counterThread1, SIGNAL(threadFinished(KCounterThread*)), this, SLOT(counterFinished(KCounterThread*)));
connect(counterThread2, SIGNAL(threadFinished(KCounterThread*)), this, SLOT(counterFinished(KCounterThread*)));
counterThread1->start();
counterThread2->start();
}
void MainWindow::counter1Changed(int value)
{
ui->progressBar1->setValue(value);
}
void MainWindow::counter2Changed(int value)
{
ui->progressBar2->setValue(value);
}
void MainWindow::counter1Finished()
{
ui->plainTextEdit->appendPlainText("Thread 1 finished!!!");
}
void MainWindow::counter2Finished()
{
ui->plainTextEdit->appendPlainText("Thread 2 finished!!!");
}
void MainWindow::counterFinished(KCounterThread *counterThread)
{
ui->plainTextEdit->appendPlainText(QString("Thread %1 finished. (This is my signal)").arg(counterThread->id()));
}
I get this output:
Thread 2 finished. (This is my signal)
Thread 2 finished!!!
Thread 1 finished. (This is my signal)
Thread 1 finished!!!
My question is:
Is this the right way to do this or is there a better way?
Thanks in advance
I'm experimenting with threads.
My goal is to write a program, which exports data from a DB to XML.
I'm planing to create 2 or 3 worker threads, that does the job.
When a thread is finished with a DB table, a new table must be assigned to the thread.
So I have to know which thread object is finished.
I wrote the following thread class for testing:
#ifndef KCOUNTERTHREAD_H
#define KCOUNTERTHREAD_H
#include <QThread>
class KCounterThread : public QThread
{
Q_OBJECT
public:
explicit KCounterThread(int id, QObject *parent = 0, int maxValue = 100, int waitTime = 100);
void run();
int maxValue() const;
void setMaxValue(int value);
int waitTime() const;
void setWaitTime(int value);
int id() const;
signals:
void counterChanged(int value);
void threadFinished(KCounterThread*);
private:
int m_maxValue;
int m_waitTime;
int m_id;
};
#endif // KCOUNTERTHREAD_H
#include "kcounterthread.h"
KCounterThread::KCounterThread(int id, QObject *parent, int maxValue, int waitTime)
: QThread(parent), m_id(id), m_maxValue(maxValue), m_waitTime(waitTime)
{
}
void KCounterThread::run()
{
for (int n = 0; n < m_maxValue; n++)
{
emit counterChanged(n);
msleep(m_waitTime);
}
emit threadFinished(this);
}
int KCounterThread::maxValue() const
{
return m_maxValue;
}
void KCounterThread::setMaxValue(int value)
{
if (!isRunning())
m_maxValue = value;
}
int KCounterThread::waitTime() const
{
return m_waitTime;
}
void KCounterThread::setWaitTime(int value)
{
if (!isRunning())
m_waitTime = value;
}
int KCounterThread::id() const
{
return m_id;
}
As you can see I emit a self declared signal threadFinished(this) at the end of the run() method.
My test program looks like this:
void MainWindow::on_pushButton2_clicked()
{
counterThread1 = new KCounterThread(1, this, 500, 10);
counterThread2 = new KCounterThread(2, this, 500, 5);
ui->progressBar1->setMaximum(counterThread1->maxValue() - 1);
ui->progressBar2->setMaximum(counterThread2->maxValue() - 1);
ui->progressBar1->setValue(0);
ui->progressBar2->setValue(0);
connect(counterThread1, SIGNAL(counterChanged(int)), this, SLOT(counter1Changed(int)));
connect(counterThread2, SIGNAL(counterChanged(int)), this, SLOT(counter2Changed(int)));
connect(counterThread1, SIGNAL(finished()), this, SLOT(counter1Finished()));
connect(counterThread2, SIGNAL(finished()), this, SLOT(counter2Finished()));
connect(counterThread1, SIGNAL(threadFinished(KCounterThread*)), this, SLOT(counterFinished(KCounterThread*)));
connect(counterThread2, SIGNAL(threadFinished(KCounterThread*)), this, SLOT(counterFinished(KCounterThread*)));
counterThread1->start();
counterThread2->start();
}
void MainWindow::counter1Changed(int value)
{
ui->progressBar1->setValue(value);
}
void MainWindow::counter2Changed(int value)
{
ui->progressBar2->setValue(value);
}
void MainWindow::counter1Finished()
{
ui->plainTextEdit->appendPlainText("Thread 1 finished!!!");
}
void MainWindow::counter2Finished()
{
ui->plainTextEdit->appendPlainText("Thread 2 finished!!!");
}
void MainWindow::counterFinished(KCounterThread *counterThread)
{
ui->plainTextEdit->appendPlainText(QString("Thread %1 finished. (This is my signal)").arg(counterThread->id()));
}
I get this output:
Thread 2 finished. (This is my signal)
Thread 2 finished!!!
Thread 1 finished. (This is my signal)
Thread 1 finished!!!
My question is:
Is this the right way to do this or is there a better way?
Thanks in advance