[Solved] How to have a progressbar with movement
-
Hi!
I'm making a GUI app which has 2 threads. The main one with the GUI and the work thread which do all the background job so as the ap is working on background the user can see it on the GUI with a label with info and a progress bar.
The point is that I need this pbar to do some movement so the user knows the app is still responding.. something like this http://www.telex.com/binary/mapLoadBar.gif.pagespeed.ce.2tpbbkj2Zu.gif but inside the progress bar.... or a pbar like http://i.msdn.microsoft.com/dynimg/IC510730.png with the last square flashing...
I've search and some forums say that you can get movement with:
@ QProgressBar bar;
bar.setMinimum(0);
bar.setMaximum(0);@But I've not be able to make it run, it just stops my app.
Thank you!
-
QProgressBar should do what you want. After setting a min and max values, you can change the pbar with the setValue(int), something like:
@
QProgressBar *pBar = new QProgressBar();
pBar->setMinimum(0);
pBar->setMaximum(10);
pBar->setValue(5);this->layout()->addWidget(pBar);
@
Or in designer, place a progress bar widget on your main window, rename it to pBar, and use:
@
ui->pBar->setMinimum(0);
ui->pBar->setMaximum(10);
ui->pBar->setValue(5);
@ -
Hi c2ypt1c,
The problem is that when I put that, there is no move in the pbar and moreover, the other gif in the GUI its stopped, but I don't know what am I doing wrong to get that behaviour ...
I have the GUI in the main thread called w and then the workthread called wt, so I suppose that I have to send a signal like this:
on wt loop:
@
emit(SigForPBar());@on w where I do other connexions:
@ connect(wt, SIGNAL(SigForPBar()), this, SLOT(ReceiveSigForPBar()));@on w:
@void MainWindow::ReceiveSigForPBar()
{
//ui->pBar->setRange(0,100);
ui->pBar->setMinimum(0);
ui->pBar->setMaximum(10);
ui->pBar->setValue(20);
}@ -
For stuff like this I query the thread at regular intervals and update the GUI elements as needed including the progress bars.
For example, a dialog that has a background thread would have these private slots:
@
void Thread_Started(void);
void Thread_Finished(void);
void Timer_HeartBeat(void);
@The 'HeartBeat' slot is called at regular intervals (using QTimer, started when the thread starts, stopped when the thread stops). The progress bar or anything else relevant is updated inside the 'HeartBeat' slot.
I usually use QMutex or equivalent inside any of the functions that query data on the thread side so I don't run into multi-thread problems.
One problem you might have if you try to update the progress bar directly from the thread is the event loop of the thread might be in limbo. You might need to call QApplication::processEvents() if you do it this way (?).
-
Yeah a query loop was going to be my other suggestion.
roseicollis, i think the problem is that you are connecting the signal to the workthread:
connect(wt,SIGNAL(),this,SLOT());
so the main window is not receiving the signal and pBar is not updated. Someone correct me if this is wrong, can't view documentation at the moment.
-
Judging by the little you have shown us, I'd suspect that you are blocking the event loop. That is: you run a tight loop somewhere in your GUI thread, that is preventing Qt from updating the progress bar to show the animation. Don't try to force the application to update from other threads than the main thread: it won't work properly and is NOT supported.
The tight-loop hypothesis in turn suggests that you may think that you are doing threading, but you are probably not.
-
Hi,
Thank you everybody for your help. As I had so much problems I decided to change my desing to another idea I liked so much too so I just use now a normal pbar. Anyway, I understand what you mean and it's obvious that I'm blocking the threads somehow.