Pyserial and pyQt

David Boddie david at boddie.org.uk
Thu Jul 23 18:58:19 EDT 2009


On Thursday 23 July 2009 10:13, Dennis Lee Bieber wrote:

> On Wed, 22 Jul 2009 10:32:51 -0700 (PDT), Seth <king.seth at gmail.com>
> declaimed the following in gmane.comp.python.general:
> 
>> Thanks for the response.  I have gone through a lot of the tutorials.
>> All of them(that I saw) seem to just deal will event-based
>> applications ie calculator, image viewer, etc.  How do I run pyserial
>> in the background and pass the information to PyQT and refresh the
>> screen?  Is there a way to have pyserial run in another thread and
>> pass the information to the UI?
>>
> So far as I've experienced (which isn't all that much), most all GUI
> frameworks support some method of defining either: 1) a work routine
> which will be called whenever the input event queue is empty -- work
> routines should be coded to do a very short, fast, bit of processing and
> return, so the event dispatcher can continue (collect one character at a
> time, or one line using a non-blocking I/O operation; or use a thread to
> collect and post via a Queue) (wx.EVT_IDLE [bind to your idle handler] &
> wx.WakeUpIdle() [call from thread after posting to queue]);

I think I can say that idle processing isn't a common idiom in PyQt
applications. After all, you can't guarantee that your application will be
idle or be able to use up idle time in a way that you can rely on, and
perhaps it isn't a good situation to be in if your framework is using up
CPU time by idling.

> 2) a timed-event which the dispatcher can call at periodic intervals (use
> a thread to collect lines from the serial port, post the lines via a
> Queue, and have the timed event check for queued data) (wx.Timer() );

In PyQt, the easiest way to do this is with a timer, connecting its
timeout() signal to a slot (method) to perform some processing. A widget
class might be adapted to do this in the following way:

  class MyWindow(QWidget):
    def __init__(self):
      QWidget.__init__(self)
      # ... other initialisation ...
      
      timer = QTimer(self)
      timer.timeout.connect(self.processData) # PyQt 4.5 signal notation
      timer.start(100)                        # every 100 milliseconds
    
    def processData(self):
      # Do your processing here.

There are various ways to use timers with PyQt, but this is a fairly simple
pattern to use.

> 3) a callback interface to the GUI event dispatcher which can be invoked
> from a separate thread (wx.CallAfter() )

I think at this point I would recommend using a separate thread. The idiom
for using threads with PyQt is quite simple, though it helps to go with the
framework and use QThread instead of Python's thread class.

> You'll have to track down the equivalent QT functions (I have to
> confess, I found the above from "wxPython in Action"; my last real GUI
> coding that needed such was nearly 20 years ago, using xt and DECWindows
> for the interface, and GKS on X for the data drawing, emulating an
> archaic Ramtek graphics engine command set. The idle/work routine
> collected commands sent via VMS mailbox to the "display" and generated
> GKS operations for them).

The people demand screenshots! ;-)

David



More information about the Python-list mailing list