Weird Behavior in QProgessBar::setValue()
-
Hi
I saw a weird behavior in the project (at least weird to me!) whenQProgressBar::setValue(int)
used!
The scenario is like this:
There is button which when clicked it would get a file from a device using API functions and there is a promise to set and a future to get for progress bar in the GUI to show the progress. easy enough I guess, ha?!
We have 3 threads, thread1 is the main thread, so theSLOT
to the button and showing the progress bar is in this thread, notice that just showing not updating.
In thread2 we will run that function in the API which will get the file from the device. Process is in a raw-for-loop which will get only 2048 Byte data each time, so we need that for-loop and each time that we get the 2048 Byte, promise will be set with the size of data (0, 2048, 4096, 6144, etc). When we get the file completely there is aSIGNAL
which I will emit, that signal is for creating and showing theQProgressBar
not for updating it.
Thread3 will update theQProgressBar
, every iteration in the loop of getting file, I am emitting aSIGNAL
, theSLOT
for that is a function like this:void MainWindows::updateProgressBar(int value) { qDebug() << "Value: " << value; progressBar->setValue(value); }
which is in the Thread1, so the
SIGNAL
is fromMyClass
andSLOT
is inMainWindows
.
And yes I know I can use this:
connect(myClassObj, SIGNAL(updateProgressNotifier(int)), progressBar, SLOT(setValue(int)));
So the weird part is: when I use the above code the program runs very fast, like 5x, and the program will crash in API!, but when I just comment
progressBar->setValue(value);
theqDebug()
will get run slowly!
I think the slow run is the accurate one, because speed of the device is not enough to give me that speed for the progress! and THAT'S the weird PART.
If it is any problem in my question, please just tell me to correct it and improve it (and I know there is a lot of problems).
Thanks. -
Hi and welcome to devnet,
You are mentioning 3 threads. Which one is the main thread ? Qt requires that all GUI related operations be done in the GUI thread which is usually the main thread. AFAIR, it can happen to a secondary thread but it means that the QApplication creation and handling must also happen in that secondary thread.
-
@SGaist sorry I was late, Thread1 which create the
QProgressBar
is the main thread.
As far as I can guess, thoseSIGNALS
from each iteration of the loop, will go in a queue and then they are going to process and update theQProgressBar
, but meanwhile, anotherSIGNAL
from other class/function will be emitted and it crashed!
But maybe it's just a false guess :\ -
@Alireza-Nikpay said in Weird Behavior in QProgessBar::setValue():
updateProgressBar(int value)
Add a check that this slot is only called in the main thread to see if you really only call it from the main thread (which you don't I would gues)
{ if (qApp->thread() != this->thread()) { qWarning() << "Created in wrong thread"; assert(false); } if (QThread::currentThread() != this->thread()) { qWarning() << "Called from wrong thread"; assert(false); } }
but meanwhile, another SIGNAL from other class/function will be emitted and it crashed!
But maybe it's just a false guess :\This can't happen when there is only one (receiver) thread is involved since then there is only one thread.
-
@Christian-Ehrlicher neither of those qWarning printed. So it called from the main thread.
But what about the weird part? why withprogressBar->setValue(value)
it gets fast and give me a crash but without it, it goes slow and doesn't give any crash. -
@Alireza-Nikpay said in Weird Behavior in QProgessBar::setValue():
t gets fast and give me a crash
Please show the backtrace.
-
@Christian-Ehrlicher sorry I don't understand what you say. Is "backtrace" is in Qt?
-
@Alireza-Nikpay said in Weird Behavior in QProgessBar::setValue():
Is "backtrace" is in Qt?
Really? Debug your application, see where the crash comes from by looking e.g. at the backtrace (aka call stack) and investigate the state of your variables.
-
@Christian-Ehrlicher Oopsie, I think it was a feature... sorry.