[PyQt] Long running processes, threads, progress dialog

Hans-Peter Jansen hpj at urpla.net
Thu Mar 24 09:27:03 GMT 2011


On Thursday 24 March 2011, 02:00:03 Catriona Johnson wrote:
> >> Hello
> >>
> >> I have a GUI application that occasionally has a number of long
> >> running processes - eg data deletions , html report generation.
> >>
> >> I have a custom progress widget that displays a spinning icon (my
> >> client didn't like the Qt QProgressDialog) which I display during
> >>long running processes - the user doesn't need to be able to
> >> interact with the GUI while this is happening.
> >>
> >> I have started to implement a worker thread to perform these long
> >> running processes. My question is do I initiate each process from
> >> the Thread's run method as follows or does each operation have its
> >> own thread ?? Do I need to use a secondary thread at all? Is there
> >> a better way ??
> >>
> >> def run(self):
> >>               if self.operation == A_DELETE:
> >>                       self.completed =
> >> AModel.model().removeRecord(self.identity) elif self.operation ==
> >> B_DELETE:
> >>                       self.completed =
> >> BModel.model().removeRecord(self.identity) elif self.operation ==
> >> REPORTS:
> >>                       self.completed =
> >> ReportWriter.generateReport() self.stop()
> >>               self.emit(SIGNAL("finished(bool)"), self.completed)
> >>               self.wait()
> >
> >You may want to read this article, which is mostly valid also for
> > PyQt:
> >
> >       http://www.linuxjournal.com/article/9602
> >
> >From a PyQt POV and depending on where the action is, the presence
> > of the GIL might want to be taken into account..
> >
> >Pete
>
> Thanks for that Pete - it is a good article.
>
> My case is not that complicated though. I am reading and sometimes
> updating binary files that contain the data for the application.
> These processes are never concurrent and do not connect to a
> database. My understanding is from the article that each process has
> a thread and the process is run from the thread's run method?

Hmm, every process _is_ a thread (in the sense of an execution unit). 
Since that cannot be stopped easily (apart from termination), there's 
no run method involved. That comes into play, if threads enter the 
picture. For every running thread (one, that got its start method 
called), your process grows another execution unit, but these need some 
preparation and following special rules, as the article shows.

> Implementing threading does seem a little bit of overkill if all I
> want is a modal progress dialog to display while the operation is
> occurring. What is the best way to do it.
>
> I did try a QProgressDialog as follows but although it was displayed
> there was no animation. I want an indeterminate progress bar
>
> progressDialog = QProgressDialog()
> progressDialog.setMinimum(0)
> progressDialog.setMaximum(0)
> progressDialog.setValue(-1) # As set in Designer
> progressDialog.show()

Ahh, I didn't understand your issue.

Try calling QtGui.QApplication.processEvents() periodically in the 
loops, but note, that calling this method has to be done from the UI 
thread, e.g. the one, that called QtGui.QApplication() before.

Pete


More information about the PyQt mailing list