"fooooo" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > This is a network app, written in wxPython and the socket module. This > is what I want to happen:
I'm not sure if this will help you, but it solved what was, for me, a more general problem: not (normally) being able to issue wxPython calls outside the GUI thread. I came up with a general-purpose thread-switcher, which, given a callable, would on invocation: queue itself up on the GUI event queue call its callable in the GUI thread (allowing arbitrary wxPython calls) pass its result back to the calling thread (or re-raise any exception there). Instead of having a dedicated queue, it uses one already in place. Because all calls using it are serialized, it had the beneficial side-effect (for me, anyway)of avoiding certain concurrency issues. (The calls to my locks module, CheckPause() and CheckCancel(), were there so the user could suspend, resume, and cancel worker threads at will, which the Python threading module does not naturally support(my locks module held some state that could be set via the GUI.) If you have no need of that, delete those lines and everything should still work (they were a late addition). import wx, threading, types import locks # my code, see remark above #------------------------------------- # decorator used to call a method (or other callable) # from the wxPython main thread (with appropriate switching) #-------------------------------------- class wxThreadSwitch(object): def __init__(self, callable): object.__init__(self) self.callable = callable def __get__(self, inst, owner=None): c = self.callable # if c is a descriptor then wrap it around # the instance as would have happened normally if not isinstance(c, types.InstanceType): try: get = c.__get__ args = [inst] if owner is not None: args.append(owner) return wxThreadSwitch(get(*args)) except AttributeError: pass # if we get here, then not a descriptor, # so return self unchanged return self def __call__(self, *args, **kwargs): if wx.Thread_IsMain(): return self.callable(*args, **kwargs) locks.CheckPause() c = self.__wxThreadCall(self.callable) wx.CallAfter(c, *args, **kwargs) return c.Result() class __wxThreadCall(object): def __init__(self, callable): assert not wx.Thread_IsMain() object.__init__(self) self.callable = callable self.result = None self.exc_info = None self.event = threading.Event() def __call__(self, *args, **kwargs): try: try: assert wx.Thread_IsMain() assert not self.event.isSet() locks.CheckCancel() self.result = self.callable(*args, **kwargs) except: self.exc_info = sys.exc_info() finally: self.event.set() def Result(self): self.event.wait() if self.exc_info: type, value, traceback = self.exc_info raise type, value, traceback return self.result A usage example would be to decorate a function or method with it: class Something: @wxThreadSwitch def someGUICallOrOther(): .... Here the method call would run via the wxThreadSwitch decorator which would do any necessary thread switching. Hope this helps John -- http://mail.python.org/mailman/listinfo/python-list