Unsolved QProgressbar unresponsive with qthread
-
@jsulm
By the time thread emits finished() signal, all my remaining things that to done(after script execution) are already executed. This makes no sense. By using QEventloop can we block the until thread emits finished() signal.? -
@meganathan as a rule of thumb,
if you're using QEventLoop or QProcessEvents, you're doing something wrong(95% chance).
-
@meganathan said in QProgressbar unresponsive with qthread:
all my remaining things that to done(after script execution) are already executed
Then do all these things in the slot connected to finished() signal as I already suggested.
"By using QEventloop can we block the until thread emits finished() signal.?" - you can, but then your progress bar will not update which was your first question in this thread, right? And if you anyway want to block, then why do you want to use threads? I don't see the point... -
here:
#ifndef SUBTHREAD_H #define SUBTHREAD_H #include <QObject> #include <QThread> class SubThread : public QThread { Q_OBJECT public: explicit SubThread(QObject *parent = nullptr); protected: virtual void run()override; signals: void status(int stat); public slots: }; #endif // SUBTHREAD_H
#include "subthread.h" #include <QTime> SubThread::SubThread(QObject *parent) : QThread(parent) { } void SubThread::run() { QTime t; t.start(); while(t.elapsed() < 10000){ if(t.elapsed() % 100 == 0) emit status(t.elapsed()/100); } }
#include <QApplication> #include <QProgressBar> #include "subthread.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QProgressBar bar; bar.show(); SubThread myThread; QObject::connect(&myThread, &SubThread::status, &bar, &QProgressBar::setValue); QObject::connect(&myThread, &SubThread::finished, &a, &QApplication::quit); myThread.start(); return a.exec(); }
-
while(t.elapsed() < 10000){
Now, you doubtless know more than I about threads, because I don't use them. But I don't get this approach. It looks like you're spinning an awfully busy loop. It's true than your main thread will run uninterrupted, but half the CPU will be executing this all the time/your mobile battery is going to drain, no? Could you explain?
This is why the OP is asking about
QEventLoop
etc. Does aQThread
run its own event loop? Does it exit when it gets to end ofrun()
or does it have to be terminated explicitly? -
@JonB I think this is just a simple example not optimised for real world usage :-)
-
@JonB I usually don't subclass QThread, but that's what the OP did so I went with the example.
It looks like you're spinning an awfully busy loop. It's true than your main thread will run uninterrupted, but half the CPU will be executing this all the time/your mobile battery is going to drain, no?
absolute correct. But this is really only a simulation of any busy calculation, that also shows, you don't need to to pause or spin the event loop to emit a signal that is handled in another thread.
Does a QThread run its own event loop? Does it exit when it gets to end of run() or does it have to be terminated explicitly?
the default QThread does indeed spin its own event loop. By overwriting
run
my subclass does this not by default.
everything inside run is executed in the new thread
If I want an event loop in SubThread, I would have to callexec()
at the end of the run function. If not, the thread finishes as soon as the run function finishes. -
@jsulm , @J-Hilk
Thank you for replies. I think I would really need to play withQThread
s if it is to sink in! I thought this was code the OP was to type in & use, that's what happens here!So just to be clear: if one really wanted to do what you have here --- emit a signal every so often --- one would set up a
QTimer
in the thread and then executeQThread::exec()
, right? -
@JonB If you want a regular Signal from the thread, triggered by a Timer then yes.
But the QTimer instance should be created inside run, or a function called from inside run. Otherwise the QTimer lives in the parent thread.
-
QThread::finished signal() emits even before the thread completed it's process. The main reason for me to go for thread approach is because on using QProcess::waitforfinished(-1) makes my QProgress bar "Not responding" state.
Even i tried to emit the signal inside the Qthread::run() to update the GUI but on using thread->wait() makes GUI unresponsive yet again.
-
QThread::finished signal() emits even before the thread completed it's process.
While you wait for @jsulm to reply, I imagine he'll want to ask you what you mean by the above? If you're not calling
exec()
it should emit whenrun()
completes. -
@meganathan it would seriously help if you show us the content of your FelixThread class
-
@J.Hilk
class FelixThread : public QThread
{
Q_OBJECTpublic:
FelixThread(QDir tempDir,QString ansysPath,QMutex & mutexObj);
public slots:
void onExecutionFinished(int exitStatus);private:
void run(); QProcess *process;
signals:
void progressChanged(int val);
};