QProgressBar doesn't update
-
Hi, I'm trying to make a progress bar for a file download, but I can't get it to work.
I'm sending information from a thread to mainwindow, where the progress bar should update, but it doesn't do anything
Here's what I have:QProgressBar* progBar = new QProgressBar; if (percentage < 0) { ui->gridLayout_Content->addWidget(progBar); } else if (percentage > 0) { qDebug() << percentage; //this works, but progBar doesn't update progBar->setValue(percentage); progBar->update(); } else if (percentage > 100) { delete progBar; }
-
@Sucharek
In principle the approach should work.- Where is this code?
- If it is really as shown, you would create a new progress bar each time this code is called to show a new value. Also is it ever called with
percentage < 0
? Maybe one of these is your issue, I don't know. - Make sure you really are sending a signal from the thread and the code above is in the main UI thread, in a slot.
- If your
percentage
is 0--100, verify what the progress bar's range is.
-
Hi @JonB, the code is as a private slot (void) in MainWindow.
I'm callingpercentage < 0
before the download starts.
I didn't set the range, so I did that, but nothing changed.
I know that the percentage values are being sent, because when I runqDebug()
, it prints the percentages just fine. -
Ok
Here is the full void in MainWindow.void MainWindow::progressBar(int percentage) { QProgressBar* progBar = new QProgressBar; progBar->setRange(0, 100); if (percentage < 0) { ui->gridLayout_Content->addWidget(progBar); } else if (percentage > 0) { qDebug() << percentage; progBar->setValue(percentage); progBar->update(); } else if (percentage > 100) { delete progBar; } }
Here is the connector:
QObject::connect(&fT,SIGNAL(progBar(const int&)),SLOT(progressBar(const int&)), Qt::QueuedConnection);
Code in thread:
//start download progBar(-1); while(true) { QString percentage = getPercentage(dir + "ROM/"); dlProg = "Downloading ROM... (" + percentage + "%)"; update(checkInternet + dlProg); //I'm also updating a label, where the percentage was shown originally progBar(percentage.toInt()); //here I'm emiting the percentage values avoidComplete += 1; if (avoidComplete > 40) {if (percentage == "100") {progBar(101); /*this is hide the bar after finished*/ break;}} msleep(100); }
-
@Sucharek
In that case please re-read my first answer. I gave you 4 possibilities. You answered for 3 of them sataisfactorily. The one you ignored is what is wrong in your code.On a separate stylistic matter:
- Use
emit
as a matter of course when emitting signals. - Don't specify
Qt::QueuedConnection
explicitly, let Qt figure that for you when the signal & slot are not in the same thread.
- Use
-
@Sucharek besides all the other issues you have with your code,
your QPorgressbar does neither have a QWidget parent, that is visible, nor do you call show on it
-> you never see any of the countless QProgressbar widgets you create.
-
@Sucharek
I said those two were stylistic.I already typed in what is wrong in your code. I told you there were 4 bullet points. I told you you had answered 3 of them satisfactorily. I told you that the one you ignored is what is wrong with your code. Also in @J-Hilk's post he mentions the same issue at one point. I don't feel like re-typing it when it's already there. If you still need help on it come back, but at least take the time to read which one you ignored first.....
-
@Sucharek , looking at your source, you create a new progress bar in a function:
void MainWindow::progressBar(int percentage) { QProgressBar* progBar = new QProgressBar;
Some place elsewhere you then connect a signal and slot:
QObject::connect(&fT,SIGNAL(progBar(const int&)),SLOT(progressBar(const int&)), Qt::QueuedConnection);
What is fT, is this actually in the same place as you create the progress bar?
What version of Qt are you using? progBar isn't a progress bar signal.
-
@JonB, ok, I think I understood the 4th solution.
I created a new progress bar everytime I called theprogBar
signal in the thread.
It's basically like this: create -> delete -> create -> delete -> ...
Here's my code:delete progBar; progBar = new QProgressBar; //progBar is now a global variable in MainWindow progBar->setRange(0, 100); if (percentage < 0) { ui->gridLayout_Content->addWidget(progBar); } else if (percentage > 0) { qDebug() << percentage; ui->gridLayout_Content->addWidget(progBar); progBar->setValue(percentage); progBar->update(); } else if (percentage > 100) { delete progBar; }
I don't know if that's what you meant, but the most important thing is, that it worked. Thanks
-
@Sucharek said in QProgressBar doesn't update:
I created a new progress bar everytime I called the progBar signal in the thread.
:) Well done, it's important to see things for yourself!
However, it still looks like you have
progBar = new QProgressBar;
in your slot?? The first 3 lines need to be somewhere else, either outside the slot or maybe in theif (percentage < 0)
case.Oh, and hang on! You have moved [copied]
ui->gridLayout_Content->addWidget(progBar);
into the case for every percentage update! That's not right [fortunately it won't have any effect]. That too belongs e.g. in theif (percentage < 0)
, or where you create the progress bar.Also, be careful about you have two
delete progBar;
s. And you do not set the member variable tonullptr
either time. This is waiting to crash on you with a "duplicate delete".....