PDA

View Full Version : Thread updates progress bar



GianMarco
9th October 2009, 11:54
Hi guys

I've created a small window (derived from QWidget) with a QProgressBar inside. Then I've created a thread class (derived from QThread). When i launch my file I create the window and the start the thread with an overloaded run method. I want that the thread (during the run) updates the progress bar at each operation. I've thought to the slots and signals system but I have problems: I've implemented a slot in the window class that updates the value of the progress bar and a signal in the thread class that invokes the slot method. In detail:



class Window: public QWidget {

data and methods
QProgressBar* pb;

public slots:
void updatePB(int);

};

void Window::updatePB(int val) { pb->setValue(val); }




class Thread: public QThread {

data and methods

Window* pointerWindow;

signals:
void signalUpdate(int);
};

Thread::Thread (Window* w) {
pointerWindow = w;
connect (this,SIGNAL(signalUpdate(int)), pointerWindow, SLOT(updatePb(int)));
}

void Thread::run() {

while (true) emit signalUpdate(30);

}


Now the questions are:
a) why doesn't it compile? It returns the error: no maching function for call to Thread::connect(Thread* const,const char*, Setup*&,const char*). I think the problem is the pointer to the window but I don't know why (I create the thread with: "Thread* th=new Thread(this);"
b) should I define the signal method?

Thanks a lot =)

yogeshgokul
9th October 2009, 12:12
First of all, use Q_OBJECT macro in you class declaration.

Ginsengelf
9th October 2009, 12:13
Hi, maybe the Q_OBJECT macro is missing in your Thread class?

Ginsengelf

GianMarco
9th October 2009, 12:32
The Q_OBJECT macro is both in thread and in window class ;)

soxs060389
11th October 2009, 19:24
Do you have an
#include <QThread> and did you read QThread doc? QThread is rather complex (in comparsion to ANSI C++ / simple QWidgets)

nikhilqt
12th October 2009, 08:53
The Q_OBJECT macro is both in thread and in window class ;)

It does not matter if Q_OBJECT macro is in thread and in window class too. Whereever you need to use Qt based functionalities you need to use this macro. since Signal/Slot is Qt functionality you need to use. As said by others, use #include <QThread> or #include <QObject>.

nikhilqt
12th October 2009, 08:58
Even I tried to set up a progress bar using multi threaded environment and communicated using signal/slot between main thread and other worker thread but it did not updated.

Later I made it in one GUI main thread only using setValue(...) method. This is useful only for sequence based progress updates i.e., calling setValue(...) everywhere step by step.:)

Cruz
12th October 2009, 14:29
I'm using the same technique to display the progress of loading a large file. What I do differently is that I handle the connections in the main Widget after instantiating the thread and then I connect the thread's signal directly to the progress bar's slot like this:



MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);

FileLoader* loader = new FileLoader();
loader->start();
connect(loader, SIGNAL(fileLoadingProgress(int)), ui.progressBar, SLOT(setValue(int)));
}


MyWidget is a QWidget anyways, but my FileLoader is my own class, so it has the Q_OBJECT defined in the header. And all it does is basicly:



void FileLoader::run()
{
load a piece of the file

emit fileLoadingProgress(100*bytesLoaded/bytesTotal);
}



Hope that helps.
Cruz