Update progress bar in another thread
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:
Quote:
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:
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
Code:
#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);
}
Code:
#ifndef GCOMPUTATIONWORKER_H
#define GCOMPUTATIONWORKER_H
#include <QObject>
class GComputationWorker
: public QObject{
Q_OBJECT
public:
GComputationWorker();
~GComputationWorker();
public slots:
void doWork();
};
#endif // GCOMPUTATIONWORKER_H
Code:
#include "gcomputationworker.h"
GComputationWorker::GComputationWorker()
{
}
GComputationWorker::~GComputationWorker()
{
}
void GComputationWorker::doWork()
{
// Start computation
// The progress bar is updated by setValue method
}
Usage:
Code:
void MainWindow::startRun()
{
ThreadManager::instance()->doComputationWork();
}
void MainWindow::onProgressBarValueChanged(int value)
{
if (ui->progressBar->maximum() == value)
{
ui->progressBar->hide();
}
}
Regards.
Re: Update progress bar in another thread
qregistermetatype: http://qt-project.org/doc/qt-4.8/qme...gisterMetaType
That will allow you to send those types across thread boundaries.
As for the timer issue, I'm not sure if that will cause your crash or not, maybe an assert.
Please give more details about what causes the crash/assert.
Have you debugged?
What line is the problem on?
What is the call stack?
You show a problem with a timer, but I do not see any code involving timers...
Re: Update progress bar in another thread
You can't modify GUI objects from another thread.
Re: Update progress bar in another thread
I haven't used timers but I get the error:
QObject::killTimers: timers cannot be stopped from another thread
Quote:
Originally Posted by
Lesiok
You can't modify GUI objects from another thread.
I haven't modified the GUI directly. I'm using cross thread signal and slot connection to set the progress on the bar.
Code:
connect(this, SIGNAL(signalUpdate(int)), mainWindowPointer, SLOT(onUpdateProgressBar(int)), Qt::QueuedConnection);
...
emit signalUpdate(valueToSet);
What's wrong?
Re: Update progress bar in another thread
What's wrong? First, what is the problem, please :) Be sure to adjust your code for qRegisterMetaType and then report any changes.
From our perspective, you have only shown some console output and some code, and said that your app crashes. We cannot be sure (without searching through Qt source code) if those console outputs are related to the app exit or not. So please respond to these pertinent questions already posed:
Quote:
Originally Posted by
amleto
Please give more details about what causes the crash/assert.
Have you debugged?
What line is the problem on?
What is the call stack?
Re: Update progress bar in another thread
The problem is that the crash is random. Sometimes doesn't occurs.
The ThreadManager class is implemented properly?
Re: Update progress bar in another thread
Only if it is only accessed via a single thread. It is not thread safe.
If you have an app with 'random' crash/assert, then throwing up pieces of code and asking, 'is it ok?', is not the best way to resolve the issue.
You need to debug your app when it crashes and give more information, or give more code. Preferably enough to compile.
Re: Update progress bar in another thread
I have solved the problem, I was accessing to a bad memory address, for this reason I got the weird message:
"QObject::killTimers: timers cannot be stopped from another thread"
Regards.
Re: Update progress bar in another thread
Another case where the OP puts up some code absolutely irrelevant to his problem. Also avoided/evaded questions asking about information obtained from debugging. This is why I like compilable examples :)