[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