[prev in list] [next in list] [prev in thread] [next in thread]
List: pykde
Subject: Re: [PyQt] Threads, events, signals and slots...
From: Dan Kripac <dankripac () gmail ! com>
Date: 2010-08-25 6:54:34
Message-ID: AANLkTimTESEmd_av4yhO2y5Diq2RqA93-LXbhfrAPpZM () mail ! gmail ! com
[Download RAW message or body]
[Attachment #2 (multipart/alternative)]
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@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@riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt
>
[Attachment #5 (text/html)]
Hi Peter,<div><br></div><div>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:</div><div><br></div><div>inside QThread.run:</div><div><br>
</div><div>self.emit( SIGNAL('updateProgress(int,int)'), currentTask, \
numTasks )</div><div><br></div><div>then on your window \
class:</div><div><br></div><div>def updateProgressBar( self, currentTask, numTasks \
):</div>
<div> self.progress_bar.setValue( int(float(currentTask)/numTasks * 100) \
)</div><div><br></div><div>Seems to work nicely without any Qt \
warnings.</div><div><br></div><div>Cheers</div><div>Dan</div><div><br><br><div \
class="gmail_quote">
On 25 August 2010 01:51, Peter Milliken <span dir="ltr"><<a \
href="mailto:peter.milliken@gmail.com">peter.milliken@gmail.com</a>></span> \
wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px \
#ccc solid;padding-left:1ex;">
Slowly working my way to learning this stuff but have a question regarding how to \
update GUI elements when threads are running.<div><br></div><div>The situation \
is:</div><div><br></div><div>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.</div>
<div><br></div><div>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.</div>
<div><br></div><div>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:</div>
<div><br></div><div>self.phase_0.setChecked(True) \
and</div><div>self.progress_bar.setValue(X)</div><div><br></div><div>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 :-)):</div>
<div><br></div><div>while True:</div><div> if pipe.poll():</div><div> msg = \
pipe.rcv()</div><div> if msg is phase 0:</div><div> \
self.phase_0.setChecked(True)</div><div> elif msg = progress:</div><div> \
self.progress_bar.setValue(X)</div>
<div> elif msg = stop</div><div> break</div><div> \
time.sleep(0.05)</div><div><br></div><div><br></div><div>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: \
</div>
<div><br></div><div>"QWidget::repaint: Recursive repaint \
detected"</div><div><br></div><div>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). </div>
<div><br></div><div>Thanks for reading this and providing any help you can \
:-)</div><div><br></div><font \
color="#888888"><div>Peter</div><div><br></div><div><br></div> \
</font><br>_______________________________________________<br> PyQt mailing list \
<a href="mailto:PyQt@riverbankcomputing.com">PyQt@riverbankcomputing.com</a><br> <a \
href="http://www.riverbankcomputing.com/mailman/listinfo/pyqt" \
target="_blank">http://www.riverbankcomputing.com/mailman/listinfo/pyqt</a><br></blockquote></div><br></div>
_______________________________________________
PyQt mailing list PyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic