[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(&#39;updateProgress(int,int)&#39;), 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">&lt;<a \
href="mailto:peter.milliken@gmail.com">peter.milliken@gmail.com</a>&gt;</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 &quot;output&quot; to display \
&quot;progress&quot; during an operation (the &quot;operation&quot; 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 &quot;updating&quot;. 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>&quot;QWidget::repaint: Recursive repaint \
detected&quot;</div><div><br></div><div>Should I be using signals/slots to update the \
GUI elements from within the &quot;2nd&quot; task? If so, what would it look like \
(please use an example that would see one of the &quot;phase&quot; 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