Frame not showing in different thread

Hi all,
Sorry for the really vague subject line, but I'm not really sure what's going on here...

In the app I've been working on (a MUD client), one of the features is scripting...

All this scripting works. I can assign aliases which trigger code etc, and that's all good, until I try and show frames...

I have a class, which is a child of wx.SizedFrame. It works fine if I Show(True) it from the command line, but it doesn't work from aliases, which are run from a different thread.

So do I need to set some property of the frame to tell it where the app object is or something if it's in a different thread?

Cheers,

Hi Chris,

···

On 2/13/2015 11:54, Chris Norman wrote:

Hi all,
Sorry for the really vague subject line, but I'm not really sure what's going on here...

In the app I've been working on (a MUD client), one of the features is scripting...

All this scripting works. I can assign aliases which trigger code etc, and that's all good, until I try and show frames...

I have a class, which is a child of wx.SizedFrame. It works fine if I Show(True) it from the command line, but it doesn't work from aliases, which are run from a different thread.

So do I need to set some property of the frame to tell it where the app object is or something if it's in a different thread?

I don't think wxPython can be run in multiple threads. IIRC all the wxPython GUI has to be in one thread.

http://wiki.wxpython.org/LongRunningTasks
http://wiki.wxpython.org/WorkingWithThreads

Werner

Hi,
Thanks for this explanation.

I read over the stuff, and honestly, some of it went over my head, so I did what I always do, and came up with a hacky but working solution.

On my frame, I have this:

def Show(self, *args, **kwargs):
  self._app = wx.App(False)
  super(CGCFrame, self).Show(*args, **kwargs)
  return self._app.MainLoop()

Not sure if it's going to cause problems in the future, but it's working fine and dandy for now.

Cheers,

···

On 13/02/2015 12:11, Werner wrote:

Hi Chris,

On 2/13/2015 11:54, Chris Norman wrote:

Hi all,
Sorry for the really vague subject line, but I'm not really sure what's going on here...

In the app I've been working on (a MUD client), one of the features is scripting...

All this scripting works. I can assign aliases which trigger code etc, and that's all good, until I try and show frames...

I have a class, which is a child of wx.SizedFrame. It works fine if I Show(True) it from the command line, but it doesn't work from aliases, which are run from a different thread.

So do I need to set some property of the frame to tell it where the app object is or something if it's in a different thread?

I don't think wxPython can be run in multiple threads. IIRC all the wxPython GUI has to be in one thread.

LongRunningTasks - wxPyWiki
WorkingWithThreads - wxPyWiki

Werner

Chris Norman wrote:

I have a class, which is a child of wx.SizedFrame. It works fine if I
Show(True) it from the command line, but it doesn't work from aliases,
which are run from a different thread.

So do I need to set some property of the frame to tell it where the app
object is or something if it's in a different thread?

What do you mean by "aliases" here? I've written an answer, but reading
your question again, I'm not sure it applies here.

This is a fundamental restriction of all of the operating systems where
wx runs. The issue is that all window manipulation is done by sending
and handling messages. Messages are associated with threads (not
windows). When you send a message to a window, it gets sent to the
message queue in the thread that created the window, and the messages
are handled by the message loop in that thread.

Because of this, all of the GUI systems assume that all GUI activity
will be done on the thread that created the window. Attempting GUI
activity from another thread can cause interlock problems.

So, if you need to do UI activity on a window from another thread, just
send a message to the window. That will do a thread shift for you.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

You might try throwing that .Show() into a .CallAfter()… it is supposedly thread-safe, and it has fixed some issues for me when using threads. See here:

···

On Friday, February 13, 2015 at 2:55:02 AM UTC-8, Chris Norman wrote:

Hi all,

Sorry for the really vague subject line, but I’m not really sure what’s
going on here…

In the app I’ve been working on (a MUD client), one of the features is
scripting…

All this scripting works. I can assign aliases which trigger code etc,
and that’s all good, until I try and show frames…

I have a class, which is a child of wx.SizedFrame. It works fine if I
Show(True) it from the command line, but it doesn’t work from aliases,
which are run from a different thread.

So do I need to set some property of the frame to tell it where the app
object is or something if it’s in a different thread?

Hi,

I tried that one, and no dice. My secondary wx.App object works

wonders though.
Cheers,

···

On 13/02/2015 18:43, Nathan McCorkle
wrote:

    On Friday, February 13, 2015 at 2:55:02 AM UTC-8, Chris Norman

wrote:

      Hi all,


      Sorry for the really vague subject line, but I'm not really

sure what’s

      going on here...




      In the app I've been working on (a MUD client), one of the

features is

      scripting...




      All this scripting works. I can assign aliases which trigger

code etc,

      and that's all good, until I try and show frames...




      I have a class, which is a child of wx.SizedFrame. It works

fine if I

      Show(True) it from the command line, but it doesn't work from

aliases,

      which are run from a different thread.




      So do I need to set some property of the frame to tell it

where the app

      object is or something if it's in a different thread?
      You might try throwing that .Show() into a .CallAfter()...

it is supposedly thread-safe, and it has fixed some issues for
me when using threads. See here:

  You received this message because you are subscribed to the Google

Groups “wxPython-users” group.

  To unsubscribe from this group and stop receiving emails from it,

send an email to wxpython-users+unsubscribe@googlegroups.com.

  For more options, visit [https://groups.google.com/d/optout](https://groups.google.com/d/optout).

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

Ah, aliases are just a feature of the program. Not really anything to do with Python.

Cheers,

···

On 13/02/2015 18:27, Tim Roberts wrote:

Chris Norman wrote:

I have a class, which is a child of wx.SizedFrame. It works fine if I
Show(True) it from the command line, but it doesn't work from aliases,
which are run from a different thread.

So do I need to set some property of the frame to tell it where the app
object is or something if it's in a different thread?

What do you mean by "aliases" here? I've written an answer, but reading
your question again, I'm not sure it applies here.

This is a fundamental restriction of all of the operating systems where
wx runs. The issue is that all window manipulation is done by sending
and handling messages. Messages are associated with threads (not
windows). When you send a message to a window, it gets sent to the
message queue in the thread that created the window, and the messages
are handled by the message loop in that thread.

Because of this, all of the GUI systems assume that all GUI activity
will be done on the thread that created the window. Attempting GUI
activity from another thread can cause interlock problems.

So, if you need to do UI activity on a window from another thread, just
send a message to the window. That will do a thread shift for you.

Then you are lucky. Do not expect this solution to work long term, or cross platform.

You must design your app to do all GUI activity on one thread.

Any GUI operations required from other threads must be marshalled to the GUI thread for execution.

Barry

···

On 13 Feb 2015, at 21:00, Chris Norman <chris.norman2@googlemail.com> wrote:

...
I tried that one, and no dice. My secondary wx.App object works wonders though.

Yeah, I think it's not really playing so nice on OS X, but it works well enough. I doubt my App's going to be used much on a mac anyways, and the core app doesn't include such a horrible flaw, it's only present in some external scripts I wrote for it.

···

On 14/02/2015 16:38, Barry Scott wrote:

On 13 Feb 2015, at 21:00, Chris Norman <chris.norman2@googlemail.com> wrote:

...
I tried that one, and no dice. My secondary wx.App object works wonders though.

Then you are lucky. Do not expect this solution to work long term, or cross platform.

You must design your app to do all GUI activity on one thread.

Any GUI operations required from other threads must be marshalled to the GUI thread for execution.

Barry