Usage of wx.CallAfter in Thread subclass?

I was taking a look at this example

http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/

And noticed that the program ran just the same when

wx.CallAfter(self.postTime, i)

was replaced with

self.postTime(i)

and

wx.CallAfter(Publisher().sendMessage, “update”, “Thread finished!”)

was replaced with

Publisher().sendMessage( “update”, “Thread finished!”)

  1. Is there a reason the author used wx.CallAfter?

Also there is a line of code that defines the class attribute self.btn as well as the variable btn

self.btn = btn = wx.Button(panel, label=“Start Thread”)

  1. Why does the author define the variable btn in addition to self.btn and then call that variable later on instead of just using self.btn? Is it un-pythonic to use the class attribute self.btn where btn will suffice?

I was taking a look at this example

http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/

And noticed that the program ran just the same when

wx.CallAfter(self.postTime, i)

was replaced with

self.postTime(i)

wx.CallAfter is thread-safe. Calling a method in wxPython directly from a thread is technically “undefined”. You may get an error today or you may not. If you do get an error, good luck finding where it happened.

and

wx.CallAfter(Publisher().sendMessage, “update”, “Thread finished!”)

was replaced with

Publisher().sendMessage( “update”, “Thread finished!”)

  1. Is there a reason the author used wx.CallAfter?

Also there is a line of code that defines the class attribute self.btn as well as the variable btn

self.btn = btn = wx.Button(panel, label=“Start Thread”)

  1. Why does the author define the variable btn in addition to self.btn and then call that variable later on instead of just using self.btn? Is it un-pythonic to use the class attribute self.btn where btn will suffice?

I think when I wrote that, I was originally going to use self.btn later on…and I may have in the code, then I refactored it and made it simpler and forgot to remove that. Sometimes I do that to save typing “self.” a lot. I try to avoid that in my newer articles though.

Mike

···

On Monday, November 11, 2013 4:30:37 PM UTC-6, RedHotChiliPepper wrote:

Hi Mike - Thanks for your prompt reply!

In regards to threading, why does wx.CallAfter execute immediately instead of waiting for the run function to complete?

Is it because the event handler run has already exited since it was called within a thread?

···

On Monday, November 11, 2013 5:42:12 PM UTC-5, Mike Driscoll wrote:

On Monday, November 11, 2013 4:30:37 PM UTC-6, RedHotChiliPepper wrote:

I was taking a look at this example

http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/

And noticed that the program ran just the same when

wx.CallAfter(self.postTime, i)

was replaced with

self.postTime(i)

wx.CallAfter is thread-safe. Calling a method in wxPython directly from a thread is technically “undefined”. You may get an error today or you may not. If you do get an error, good luck finding where it happened.

and

wx.CallAfter(Publisher().sendMessage, “update”, “Thread finished!”)

was replaced with

Publisher().sendMessage( “update”, “Thread finished!”)

  1. Is there a reason the author used wx.CallAfter?

Also there is a line of code that defines the class attribute self.btn as well as the variable btn

self.btn = btn = wx.Button(panel, label=“Start Thread”)

  1. Why does the author define the variable btn in addition to self.btn and then call that variable later on instead of just using self.btn? Is it un-pythonic to use the class attribute self.btn where btn will suffice?

I think when I wrote that, I was originally going to use self.btn later on…and I may have in the code, then I refactored it and made it simpler and forgot to remove that. Sometimes I do that to save typing “self.” a lot. I try to avoid that in my newer articles though.

Mike

MAYBE it ran just the same, for a while, on your one system, in that
one circumstance. It is a rule that you can change a window in any
thread other than the thread that created the window. The operating
system does not do any interlocking. You might get away with it for
a while, but sooner or later it will break, and you won’t understand
right.
Get in the habit of doing it the right way. The CallAfter queues up
a message that will be handled by the window’s message loop, which
is guaranteed to be running in the correct thread.
That’s not a class attribute. It’s an object attribute.
No; there are two reasons, neither of them very compelling. One, it
saves typing. Two, it is very slightly faster. In an
initialization function, the time savings is irrelevant.
Often, this kind of thing happens because the code was originally
written with just a local variable, and then at some point the
author realized he needed to refer to the button in another
function, so he saved it in an object attribute.

···

RedHotChiliPepper wrote:

I was taking a look at this example

http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/

And noticed that the program ran just the same when

          wx.CallAfter(self.postTime,

i)

was replaced with

self.postTime(i)

and

          wx.CallAfter(Publisher().sendMessage,

“update”, “Thread finished!”)

was replaced with

          Publisher().sendMessage(

“update”, “Thread finished!”)

  1. Is there a reason the author used wx.CallAfter?
      Also there is a line of code that defines the class

attribute self.btn
as well as the variable btn

        self.btn = btn =

wx.Button(panel, label=“Start Thread”)

  1. Why does the author define the variable btn in addition to self.btn and then call
    that variable later on instead of just using self.btn ? Is it
    un-pythonic to use the class attribute self.btn where btn will suffice?
-- Tim Roberts, Providenza & Boekelheide, Inc.

timr@probo.com

You’re thinking linearly. The wx.CallAfter queues up a message for
the message loop. That message loop is in a different thread, which
might be running in another processor at exactly the same time. So,
it’s possible that the “postTime” function gets called before the
“run” function gets a chance to move on, OR it’s possible that the
“run” function will finish first and then “postTime” will run, OR
it’s possible that both functions run at exactly the same time.
That’s the fun of multithreading, and that’s why you have to be
careful about protecting shared data with locks.

···

RedHotChiliPepper wrote:

Hi Mike - Thanks for your prompt reply!

In regards to threading, why does wx.CallAfter execute immediately instead
of waiting for the run
function to complete?

Is it because the event handler run has already exited since it was called
within a thread?

-- Tim Roberts, Providenza & Boekelheide, Inc.

timr@probo.com

In regards to threading, why does wx.CallAfter execute immediately instead

of waiting for the run function to complete?

Is it because the event handler run has already exited since it was called
within a thread?

You're thinking linearly. The wx.CallAfter queues up a message for the
message loop. That message loop is in a different thread, which might be
running in another processor at exactly the same time. So, it's possible
that the "postTime" function gets called before the "run" function gets a
chance to move on...

···

----------------------

Great "Gotcha!" Tip, Tim!

I use wx.CallAfter all the time, but in event-processing methods, so the
event processing (being in the GUI thread) always completes before the the
called function. But this is an excellent point about the call just being
queued for execution by the GUI thread's message loop if used from a
different thread!

--
View this message in context: http://wxpython-users.1045709.n5.nabble.com/Usage-of-wx-CallAfter-in-Thread-subclass-tp5719139p5719163.html
Sent from the wxPython-users mailing list archive at Nabble.com.