[PyKDE] gui update fails
Matt Newell
newellm at blur.com
Mon Feb 19 18:59:30 GMT 2007
On Monday 19 February 2007 08:27, Michael Lara wrote:
> Hi everyone
>
> I am using Qt 4.2.2 and PyQt 4.1 on Linux. The mailing list archives show
> that this is a rather common question, yet I couldn't find out why the
> following code isn't working. I am simply trying to update the GUI as a
> thread goes through three stages:
>
> - worker thread hasn't been started
> - worker thread is working
> - worker thread has finished
>
> In the code below, why doesn't the caption of the QPushButton get updated
> to "running..." the moment MyQPushButton.runThread() is invoked? On my
> system, the button initially reads "Click to run thread!". Then I click it,
> the app prints to stdout
>
> running...
> thread sleeping...
> thread finished
>
> and then the button text becomes "Done!". Why isn't the button caption
> updated (to "running...") while the thread is sleeping?
Because you never let the main thread return to the event loop. Calling update
on the widget just marks it to be updated during the next paint event, which
will happen right away when you return to the event loop.
>
> Thanks in advance for any advice
>
> Michael
>
> #!/usr/bin/env python
>
> import sys, time
>
> from PyQt4.QtGui import *
> from PyQt4.QtCore import *
>
> class Th(QThread):
>
> def run(self):
> print "thread sleeping..."
> time.sleep(2)
> print "thread finished"
> return
> pass
>
> class MyQPushButton(QPushButton):
>
> def __init__(self, caption, parent = None):
>
> QPushButton.__init__(self, caption, parent)
> self.connect(self, SIGNAL("clicked()"), self.runThread)
> return
>
> def runThread(self):
>
> self.setText("running...") # <<== NEVER HAPPENS?!
Should be the end of the function, if you want to know when the thread is
started/finished, connect to it's started()/finished() signal.
> self.update()
> print "running..."
>
> th = Th()
> th.start()
>
Looping here keeps the main thread from getting back to the event loop, hence
the gui will not be updated. You could simply add a processEvents call here
and everything would work, but it's bad coding practice.
> while not th.isFinished():
>
> self.update()
> time.sleep(0.1)
> pass
> self.setText("Done!")
> return
> pass
>
> app = QApplication(sys.argv)
>
> button = MyQPushButton("Click to run thread!")
>
> button.show()
>
> app.exec_()
>
Matt
> _______________________________________________
> PyKDE mailing list PyKDE at mats.imk.fraunhofer.de
> http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
More information about the PyQt
mailing list