ear9mrn
10th November 2009, 17:34
Hi,
I am trying to update a progressbar in a main widget from a job run from a qthread via a custom event.
The objective is to ensure the progress bar is updated as the "long job" is running. At the moment if I just run job from the main class the gui just freezes until the job is complete. I think threading it is the best of option for "real time" update of the qprogressbar. See my code below of a simple example of what I am trying to do. I do not think the thread is emitting the event correctly (i just get cout of thread and not event !!), I think the problem may be with the qobject receiver in the postevet, qApp.
Any suggestions or help would be great, its very frustating as I feel I am close to a solution.
main.cpp
/*
* external loop main.cpp
*/
#include "externalloop.h"
#include <qapplication.h>
int main( int argc, char **argv )
{
QApplication a( argc, argv );
ExternalLoop externalloop;
externalloop.resize( 200, 100 );
externalloop.setCaption( "ExternalLoop" );
a.setMainWidget( &externalloop );
externalloop.show();
return a.exec();
}
extarnalloop.h
/*
* externalloop.h
*/
#ifndef GREY_BUTTON_H
#define GREY_BUTTON_H
#include <qwidget.h>
#include <qpushbutton.h>
#include <qprogressbar.h>
#include <qapplication.h>
#include <qlayout.h>
#include <qevent.h>
#include <qthread.h>
#include <iostream>
class QProgressBar;
class QPushButton;
class ExternalLoop : public QWidget
{
Q_OBJECT
public:
ExternalLoop( QWidget *parent = 0, const char *name = 0 );
QPushButton *pb1;
QProgressBar *myProgress;
void customEvent(QCustomEvent * e);
private:
public slots:
void theLoop();
};
class myEvent : public QCustomEvent
{
public:
myEvent(int i): QCustomEvent( QEvent::User ),v(i){};
int done() const { return v; };
private:
int v;
};
class MyThread : public QThread {
public:
virtual void run();
};
#endif
externalloop.cpp
/*
* externalloop.cpp
*/
#include "externalloop.h"
using namespace std;
ExternalLoop::ExternalLoop( QWidget *parent, const char *name )
: QWidget( parent, name )
{
QGridLayout *grid1 = new QGridLayout(this,2,1,10);
pb1 = new QPushButton("Loop", this);
grid1->addWidget( pb1, 0, 0 );
connect(pb1, SIGNAL( clicked() ), this, SLOT( theLoop() ) );
myProgress = new QProgressBar(100, this);
grid1->addWidget( myProgress, 1, 0);
myProgress->setTotalSteps(10);
}
void ExternalLoop::theLoop()
{
MyThread a;
a.start();
a.wait();
}
void ExternalLoop::customEvent(QCustomEvent * e)
{
myEvent* lEvent = (myEvent*)e;
int var = lEvent->done();
myProgress->setProgress(var);
qApp->processEvents();
cout << "event " << var << endl;
}
void MyThread::run()
{
for( int count = 0; count < 11; count++ ) {
sleep( 1 );
cout << "thread " << count << endl;
myEvent* lEvent = new myEvent(count);
QApplication::postEvent( qApp, lEvent);
}
}
I am trying to update a progressbar in a main widget from a job run from a qthread via a custom event.
The objective is to ensure the progress bar is updated as the "long job" is running. At the moment if I just run job from the main class the gui just freezes until the job is complete. I think threading it is the best of option for "real time" update of the qprogressbar. See my code below of a simple example of what I am trying to do. I do not think the thread is emitting the event correctly (i just get cout of thread and not event !!), I think the problem may be with the qobject receiver in the postevet, qApp.
Any suggestions or help would be great, its very frustating as I feel I am close to a solution.
main.cpp
/*
* external loop main.cpp
*/
#include "externalloop.h"
#include <qapplication.h>
int main( int argc, char **argv )
{
QApplication a( argc, argv );
ExternalLoop externalloop;
externalloop.resize( 200, 100 );
externalloop.setCaption( "ExternalLoop" );
a.setMainWidget( &externalloop );
externalloop.show();
return a.exec();
}
extarnalloop.h
/*
* externalloop.h
*/
#ifndef GREY_BUTTON_H
#define GREY_BUTTON_H
#include <qwidget.h>
#include <qpushbutton.h>
#include <qprogressbar.h>
#include <qapplication.h>
#include <qlayout.h>
#include <qevent.h>
#include <qthread.h>
#include <iostream>
class QProgressBar;
class QPushButton;
class ExternalLoop : public QWidget
{
Q_OBJECT
public:
ExternalLoop( QWidget *parent = 0, const char *name = 0 );
QPushButton *pb1;
QProgressBar *myProgress;
void customEvent(QCustomEvent * e);
private:
public slots:
void theLoop();
};
class myEvent : public QCustomEvent
{
public:
myEvent(int i): QCustomEvent( QEvent::User ),v(i){};
int done() const { return v; };
private:
int v;
};
class MyThread : public QThread {
public:
virtual void run();
};
#endif
externalloop.cpp
/*
* externalloop.cpp
*/
#include "externalloop.h"
using namespace std;
ExternalLoop::ExternalLoop( QWidget *parent, const char *name )
: QWidget( parent, name )
{
QGridLayout *grid1 = new QGridLayout(this,2,1,10);
pb1 = new QPushButton("Loop", this);
grid1->addWidget( pb1, 0, 0 );
connect(pb1, SIGNAL( clicked() ), this, SLOT( theLoop() ) );
myProgress = new QProgressBar(100, this);
grid1->addWidget( myProgress, 1, 0);
myProgress->setTotalSteps(10);
}
void ExternalLoop::theLoop()
{
MyThread a;
a.start();
a.wait();
}
void ExternalLoop::customEvent(QCustomEvent * e)
{
myEvent* lEvent = (myEvent*)e;
int var = lEvent->done();
myProgress->setProgress(var);
qApp->processEvents();
cout << "event " << var << endl;
}
void MyThread::run()
{
for( int count = 0; count < 11; count++ ) {
sleep( 1 );
cout << "thread " << count << endl;
myEvent* lEvent = new myEvent(count);
QApplication::postEvent( qApp, lEvent);
}
}