I have an wxPython app that reads
data from a USB HID device and displays the result in a ListCtrl.
While the data is being read, a progress bar (gauge) is updated.
A low-level read of the USB HID data (without any wx GUI stuff)
takes about 5-6 seconds, however when called via the GUI the
progress bar takes about 30 seconds to complete. This is a huge
(approx 500%) performance hit.
I tracked it down to using the @wxAnyThread.anythread decorator,
which I am using for thread safe updating of the GUI, as the
actual reading of the data is happening in a worker thread, via
wxDelayedResult.startWorker(). If I remove the @wxAnyThread.anythread decorator the
progress bar updates and completes in approximately 6 seconds.
This is what I want, but I am uncomfortable as I know I should
only update GUI items from a single thread (i.e. not a worker thread).
I'm using python-2.7.10 (python-2.7.10-macosx10.6), with wxPython3.0.2.0 (wxPython3.0-osx-3.0.2.0-cocoa-py2.7).
Anyone know why wxAnyThread is causing such a big performance hit?
I know wxAnyThread is quite old (last updated March 2010) and is
probably not optimised for later versions of python and wxPython.
Is there a better way of updating the GUI from worker threads with
wxPython 3.0 ??
Thanks, Brendan.
After much googling, wx.CallAfter() seemed like it was worth a shot. Hey, it worked, so I’ve totally ditched wx.AnyThread and replaced it with wx.CallAfter(). I didn’t think this would work as I thought the updates would only take affect after the thread had completed, rather that through each chunk of data being read by the thread, but I guess the I/O calls must block and allow the main GUI thread to process things – or maybe I’ve just misunderstood how wx.CallAfter() works with thread ??
···
On Wednesday, 8 July 2015 11:37:54 UTC+10, Brendan Simon wrote:
I have an wxPython app that reads
data from a USB HID device and displays the result in a ListCtrl.
While the data is being read, a progress bar (gauge) is updated.
A low-level read of the USB HID data (without any wx GUI stuff)
takes about 5-6 seconds, however when called via the GUI the
progress bar takes about 30 seconds to complete. This is a huge
(approx 500%) performance hit.
I tracked it down to using the @wxAnyThread.anythread decorator,
which I am using for thread safe updating of the GUI, as the
actual reading of the data is happening in a worker thread, via
wxDelayedResult.startWorker(). If I remove the @wxAnyThread.anythread decorator the
progress bar updates and completes in approximately 6 seconds.
This is what I want, but I am uncomfortable as I know I should
only update GUI items from a single thread (i.e. not a worker thread).
I'm using python-2.7.10 (python-2.7.10-macosx10.6), with wxPython3.0.2.0 (wxPython3.0-osx-3.0.2.0-cocoa-py2.7).
Anyone know why wxAnyThread is causing such a big performance hit?
I know wxAnyThread is quite old (last updated March 2010) and is
probably not optimised for later versions of python and wxPython.
Is there a better way of updating the GUI from worker threads with
wxPython 3.0 ??
Thanks, Brendan.
There’s no blocking here. wx.CallAfter just posts a message in the
message queue for the main thread and continues to work. The main
thread is still running your message loop at the same time your
worker thread is doing it’s thing. It notices the new message and
starts executing the handler.
If you only have one processor, then the two threads do have to
share the CPU, but if you have multiple processors, the two can
literally run at the exact same time.
···
Brendan Simon wrote:
After much googling,
wx.CallAfter() seemed like it was worth a shot. Hey, it
worked, so I’ve totally ditched wx.AnyThread and replaced it
with wx.CallAfter(). I didn’t think this would work as I
thought the updates would only take affect after the thread
had completed, rather that through each chunk of data being
read by the thread, but I guess the I/O calls must block and
allow the main GUI thread to process things – or maybe I’ve
just misunderstood how wx.CallAfter() works with thread ??
-- Tim Roberts, Providenza & Boekelheide, Inc.
timr@probo.com