Hi all,
I have an application with an additional thread that handles a heavy process for the purpose of the GUI doesn't lock.
In this process is needed update a progress bar that resides in the main thread but sometimes the application closes unexpectedly.
I get these messages in application output:
QObject::connect: Cannot queue arguments of type 'QTextBlock'
(Make sure 'QTextBlock' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
QObject::killTimers: timers cannot be stopped from another thread
How can I solve this issue?
My code:
#ifndef THREADMANAGER_H
#define THREADMANAGER_H
#include <QObject>
class GComputationWorker;
class ThreadManager
: public QObject {
Q_OBJECT
public:
// constructors and destructor
/**
* Returns an instance of this class. When called for the first
* time, a new instance is created and returned. After that,
* calling InstanceL returns the same instance that was created
* earlier.
*
* @return A pointer to a ThreadManager object
*/
static ThreadManager* instance();
private:
// constructor
/**
* Default constructor is private because we are using the
* singleton design pattern.
*/
ThreadManager();
public:
void doComputationWork();
private:
static ThreadManager *_instance;
GComputationWorker *computationWorker;
};
#endif // THREADMANAGER_H
#ifndef THREADMANAGER_H
#define THREADMANAGER_H
#include <QObject>
class QThread;
class GComputationWorker;
class ThreadManager: public QObject
{
Q_OBJECT
public:
// constructors and destructor
/**
* Returns an instance of this class. When called for the first
* time, a new instance is created and returned. After that,
* calling InstanceL returns the same instance that was created
* earlier.
*
* @return A pointer to a ThreadManager object
*/
static ThreadManager* instance();
private:
// constructor
/**
* Default constructor is private because we are using the
* singleton design pattern.
*/
ThreadManager();
public:
void doComputationWork();
private:
static ThreadManager *_instance;
QThread *computationThread;
GComputationWorker *computationWorker;
};
#endif // THREADMANAGER_H
To copy to clipboard, switch view to plain text mode
#include "threadmanager.h"
#include "gcomputationworker.h"
#include <QThread>
ThreadManager * ThreadManager::_instance = NULL;
ThreadManager::ThreadManager()
{
_instance = NULL;
computationWorker = new GComputationWorker;
computationWorker->moveToThread(computationThread);
}
ThreadManager* ThreadManager::instance()
{
if (ThreadManager::_instance == 0)
ThreadManager::_instance = new ThreadManager();
return ThreadManager::_instance;
}
void ThreadManager::doComputationWork()
{
computationOperFinished = false;
computationThread->start();
computationThread
->setPriority
(QThread::NormalPriority);
QMetaObject::invokeMethod(computationWorker,
"doWork", Qt
::QueuedConnection);
}
#include "threadmanager.h"
#include "gcomputationworker.h"
#include <QThread>
ThreadManager * ThreadManager::_instance = NULL;
ThreadManager::ThreadManager()
{
_instance = NULL;
computationThread = new QThread;
computationWorker = new GComputationWorker;
computationWorker->moveToThread(computationThread);
}
ThreadManager* ThreadManager::instance()
{
if (ThreadManager::_instance == 0)
ThreadManager::_instance = new ThreadManager();
return ThreadManager::_instance;
}
void ThreadManager::doComputationWork()
{
computationOperFinished = false;
computationThread->start();
computationThread->setPriority(QThread::NormalPriority);
QMetaObject::invokeMethod(computationWorker, "doWork", Qt::QueuedConnection);
}
To copy to clipboard, switch view to plain text mode
#ifndef GCOMPUTATIONWORKER_H
#define GCOMPUTATIONWORKER_H
#include <QObject>
class GComputationWorker
: public QObject{
Q_OBJECT
public:
GComputationWorker();
~GComputationWorker();
public slots:
void doWork();
};
#endif // GCOMPUTATIONWORKER_H
#ifndef GCOMPUTATIONWORKER_H
#define GCOMPUTATIONWORKER_H
#include <QObject>
class GComputationWorker : public QObject
{
Q_OBJECT
public:
GComputationWorker();
~GComputationWorker();
public slots:
void doWork();
};
#endif // GCOMPUTATIONWORKER_H
To copy to clipboard, switch view to plain text mode
#include "gcomputationworker.h"
GComputationWorker::GComputationWorker()
{
}
GComputationWorker::~GComputationWorker()
{
}
void GComputationWorker::doWork()
{
// Start computation
// The progress bar is updated by setValue method
}
#include "gcomputationworker.h"
GComputationWorker::GComputationWorker()
{
}
GComputationWorker::~GComputationWorker()
{
}
void GComputationWorker::doWork()
{
// Start computation
// The progress bar is updated by setValue method
}
To copy to clipboard, switch view to plain text mode
Usage:
void MainWindow::startRun()
{
ThreadManager::instance()->doComputationWork();
}
void MainWindow::onProgressBarValueChanged(int value)
{
if (ui->progressBar->maximum() == value)
{
ui->progressBar->hide();
}
}
void MainWindow::startRun()
{
ThreadManager::instance()->doComputationWork();
}
void MainWindow::onProgressBarValueChanged(int value)
{
if (ui->progressBar->maximum() == value)
{
ui->progressBar->hide();
}
}
To copy to clipboard, switch view to plain text mode
Regards.
Bookmarks