[PyQt] Threads, events, signals and slots...

Dan Kripac dankripac at gmail.com
Wed Aug 25 07:54:34 BST 2010


Hi Peter,

When I have done this in my PyQt apps I simply send a signal straight from
the QThread to a function that updates the QProgressBar i.e:

inside QThread.run:

self.emit( SIGNAL('updateProgress(int,int)'), currentTask, numTasks )

then on your window class:

def updateProgressBar( self, currentTask, numTasks ):
    self.progress_bar.setValue( int(float(currentTask)/numTasks * 100) )

Seems to work nicely without any Qt warnings.

Cheers
Dan


On 25 August 2010 01:51, Peter Milliken <peter.milliken at gmail.com> wrote:

> Slowly working my way to learning this stuff but have a question regarding
> how to update GUI elements when threads are running.
>
> The situation is:
>
> 1. I have some radiobuttons that I use for input and output: input by the
> user and then for "output" to display "progress" during an operation (the
> "operation" is a task that runs in a QThread instance). The radiobuttons are
> grouped into a QGroupBox are there are 3 of them to indicate 3 phases of a
> total operation. The user selects a start phase and then instigates a
> process (via a QCommandLinkButton), as the process progresses from the start
> phase to the final phase the phase buttons must be updated.
>
> 2. I have a QProgressBar to indicate the progress (0 - 100%) within each
> phase (indicated by the previously mentioned phase buttons). So each phase
> progresses through 0 - 100% completion before advancing to the next phase.
>
> So basically the user selects which phase they want to start at (0, 1 or 2)
> and then press a button to instigate a QThread that performs the actions.
> The progress is communicated back from the thread via messages in a pipe. To
> receive the messages and update the GUI elements I start another QThread -
> this is one of the methods of the application GUI class and goes into a
> while loop, receiving messages from the thread that is doing the job and
> directly making calls to GUI elements like:
>
> self.phase_0.setChecked(True) and
> self.progress_bar.setValue(X)
>
> At the end of the while loop I do a time.sleep() command to allow the Qt
> event loop to run and presumably update any GUI elements that need
> "updating". So the code looks like this (mix of pseudo code and real code
> :-)):
>
> while True:
>   if pipe.poll():
>     msg = pipe.rcv()
>     if msg is phase 0:
>       self.phase_0.setChecked(True)
>     elif msg = progress:
>       self.progress_bar.setValue(X)
>     elif msg = stop
>        break
>   time.sleep(0.05)
>
>
> This seems to work quite well, however, every now and again, when switching
> between Windows applications etc while the process that I have tasked is
> running, I get an error/warning message:
>
> "QWidget::repaint: Recursive repaint detected"
>
> Should I be using signals/slots to update the GUI elements from within the
> "2nd" task? If so, what would it look like (please use an example that would
> see one of the "phase" radiobuttons updated).
>
> Thanks for reading this and providing any help you can :-)
>
> Peter
>
>
>
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20100825/4ef19478/attachment-0001.html>


More information about the PyQt mailing list