SetFocus problem

Hello to all,

I am having a problem on the SetFocus method of an element.
Basically the wxApp receives an external call for it to focus a particular button on the frame’s gui.
However the Focus is not being passed even if the element ‘AcceptsFocus’.

I have here an example: the application is run and a webservice talks to it. This webservice allows, via a client, to set the Focus on a particular button. However nothing happens.
I am trying to solve this issue and cant figure out what is going on. I already tried asking on IRC etc… but nobody helps me !

Please check here the webservice server code:

server.py

import SOAPpy
import wx
from wx import xrc
import thread

g__gui_xrc = ‘’’<?xml version="1.0" encoding="utf-8"?>


Primary Frame


2
1
0
0



1
wxEXPAND
5

bt1



1
wxEXPAND
5

bt2



1
wxEXPAND
5

bt3



1
wxEXPAND
5

bt4






Secondary Frame


This is a dynamically created frame.



‘’’

def launch_gui(i__object, i__gui_app):
app = i__gui_app(0)
app.m__controller = i__object
app.m__controller.m__gui_running = app
app.MainLoop()

class GuiApp(wx.App):
def OnInit(self):
print g__gui_xrc
self.m__controller = None
self.m__xrc_ressource = xrc.EmptyXmlResource()
self.m__xrc_ressource.LoadFromString(g__gui_xrc)
self.m__capture_frame = self.m__xrc_ressource.LoadFrame(None, ‘mainFrame’)
self.m__main_panel = xrc.XRCCTRL(self.m__capture_frame, ‘mainPanel’)
self.m__button_one = xrc.XRCCTRL(self.m__capture_frame, ‘button_one’)
self.m__button_two = xrc.XRCCTRL(self.m__capture_frame, ‘button_two’)
self.m__button_three = xrc.XRCCTRL(self.m__capture_frame, ‘button_three’)
self.m__button_four = xrc.XRCCTRL(self.m__capture_frame, ‘button_four’)
self.m__capture_frame.Bind(wx.EVT_BUTTON, self.buttonClick, self.m__button_one)
self.m__capture_frame.Show()
return True

def buttonClick(self, i__event=None):
    self.m__controller.printSomething()

def setElementFocus(self, i__button_name=None):
    print 'setting element focus to ', i__button_name
    l__obj = getattr(self, i__button_name)
    self.m__main_panel.SetFocus()
    print 'accepts focus:',l__obj.AcceptsFocus()
    l__obj.SetFocus()
    l__obj.SetFocusFromKbd()
    l__obj.SetBackgroundColour(wx.Colour(255,255,255))

class GuiController():
def init(self):
self.m__gui_running = False
self.m__gui_thread = False
self.m__something = ‘bla bla bla’

def printSomething(self):
    print self.m__something

def showGui(self):
    if not self.m__gui_running:
        #self.m__gui_running = GuiApp(0)
        #self.m__gui_thread = thread.start_new_thread(launch_gui, (self, GuiApp))
        self.m__gui_thread = thread.start_new_thread(launch_gui, (self, GuiApp))

def killGui(self):
    if self.m__gui_running:
        print 'killing gui'

def getStatus(self):
    if self.m__gui_running:
        return True
    else:
        return False

def focusItem(self, i__button_name=None):
    self.m__gui_running.setElementFocus(i__button_name)

def show_gui():
if g__gui_controller:
g__gui_controller.showGui()
return True
return False

def kill_gui():
if g__gui_controller:
g__gui_controller.killGui()
return True
return False

def get_status():
if g__gui_controller:
return g__gui_controller.getStatus()

def set_text(i__text=None):
if g__gui_controller:
g__gui_controller.m__something = i__text

def set_focus(i__button_name=None):
if g__gui_controller:
g__gui_controller.focusItem(i__button_name)

if name == ‘main’:
server = SOAPpy.SOAPServer((’’,12321))
g__gui_controller = GuiController()
server.registerFunction(show_gui)
server.registerFunction(get_status)
server.registerFunction(set_text)
server.registerFunction(set_focus)
server.serve_forever()

and a simple client:

client.py

import SOAPpy
s = SOAPpy.SOAPProxy(‘http://localhost:12321’)
s.show_gui()
s.set_focus(‘m__button_two’)

···

Windows Live™: Keep your life in sync. Check it out!

Patricio,

Hello to all,

I am having a problem on the SetFocus method of an element.
Basically the wxApp receives an external call for it to focus a particular button on the frame's gui.
However the Focus is not being passed even if the element 'AcceptsFocus'.

I have here an example: the application is run and a webservice talks to it. This webservice allows, via a client, to set the Focus on a particular button. However nothing happens.
I am trying to solve this issue and cant figure out what is going on. I already tried asking on IRC etc... but nobody helps me !

Please check here the webservice server code:

# server.py
import SOAPpy
import wx
from wx import xrc
import thread

g__gui_xrc = '''<?xml version="1.0" encoding="utf-8"?>
<resource>
  <object class="wxFrame" name="mainFrame">
    <title>Primary Frame</title>
    <object class="wxPanel" name="mainPanel">
      <object class="wxFlexGridSizer">
        <rows>2</rows>
        <cols>1</cols>
        <vgap>0</vgap>
        <hgap>0</hgap>
        <growablecols></growablecols>
        <growablerows></growablerows>
        <object class="sizeritem">
          <option>1</option>
          <flag>wxEXPAND</flag>
          <border>5</border>
          <object class="wxButton" name="button_one">
            <label>bt1</label>
          </object>
        </object>
        <object class="sizeritem">
          <option>1</option>
          <flag>wxEXPAND</flag>
          <border>5</border>
          <object class="wxButton" name="button_two">
            <label>bt2</label>
          </object>
        </object>
        <object class="sizeritem">
          <option>1</option>
          <flag>wxEXPAND</flag>
          <border>5</border>
          <object class="wxButton" name="button_three">
            <label>bt3</label>
          </object>
        </object>
        <object class="sizeritem">
          <option>1</option>
          <flag>wxEXPAND</flag>
          <border>5</border>
          <object class="wxButton" name="button_four">
            <label>bt4</label>
          </object>
        </object>
      </object>
    </object>
  </object>
  <object class="wxFrame" name="nextFrame">
    <title>Secondary Frame</title>
    <object class="wxPanel" name="nextPanel">
      <object class="wxStaticText" name="label">
        <label>This is a dynamically created frame.</label>
      </object>
    </object>
  </object>
</resource>'''

def launch_gui(i__object, i__gui_app):
    app = i__gui_app(0)
    app.m__controller = i__object
    app.m__controller.m__gui_running = app
    app.MainLoop()

class GuiApp(wx.App):
    def OnInit(self):
        print g__gui_xrc
        self.m__controller = None
        self.m__xrc_ressource = xrc.EmptyXmlResource()
        self.m__xrc_ressource.LoadFromString(g__gui_xrc)
        self.m__capture_frame = self.m__xrc_ressource.LoadFrame(None, 'mainFrame')
        self.m__main_panel = xrc.XRCCTRL(self.m__capture_frame, 'mainPanel')
        self.m__button_one = xrc.XRCCTRL(self.m__capture_frame, 'button_one')
        self.m__button_two = xrc.XRCCTRL(self.m__capture_frame, 'button_two')
        self.m__button_three = xrc.XRCCTRL(self.m__capture_frame, 'button_three')
        self.m__button_four = xrc.XRCCTRL(self.m__capture_frame, 'button_four')
        self.m__capture_frame.Bind(wx.EVT_BUTTON, self.buttonClick, self.m__button_one)
        self.m__capture_frame.Show()
        return True
       def buttonClick(self, i__event=None):
        self.m__controller.printSomething()

    def setElementFocus(self, i__button_name=None):
        print 'setting element focus to ', i__button_name
        l__obj = getattr(self, i__button_name)
        self.m__main_panel.SetFocus()
        print 'accepts focus:',l__obj.AcceptsFocus()
        l__obj.SetFocus()
        l__obj.SetFocusFromKbd()
        l__obj.SetBackgroundColour(wx.Colour(255,255,255))

class GuiController():
    def __init__(self):
        self.m__gui_running = False
        self.m__gui_thread = False
        self.m__something = 'bla bla bla'
       def printSomething(self):
        print self.m__something

    def showGui(self):
        if not self.m__gui_running:
            #self.m__gui_running = GuiApp(0)
            #self.m__gui_thread = thread.start_new_thread(launch_gui, (self, GuiApp))
            self.m__gui_thread = thread.start_new_thread(launch_gui, (self, GuiApp))
       def killGui(self):
        if self.m__gui_running:
            print 'killing gui'
       def getStatus(self):
        if self.m__gui_running:
            return True
        else:
            return False

    def focusItem(self, i__button_name=None):
        self.m__gui_running.setElementFocus(i__button_name)

def show_gui():
    if g__gui_controller:
        g__gui_controller.showGui()
        return True
    return False

def kill_gui():
    if g__gui_controller:
        g__gui_controller.killGui()
        return True
    return False

def get_status():
    if g__gui_controller:
        return g__gui_controller.getStatus()

def set_text(i__text=None):
    if g__gui_controller:
        g__gui_controller.m__something = i__text

def set_focus(i__button_name=None):
    if g__gui_controller:
        g__gui_controller.focusItem(i__button_name)

if __name__ == '__main__':
    server = SOAPpy.SOAPServer(('',12321))
    g__gui_controller = GuiController()
    server.registerFunction(show_gui)
    server.registerFunction(get_status)
    server.registerFunction(set_text)
    server.registerFunction(set_focus)
    server.serve_forever()

and a simple client:

# client.py
import SOAPpy
s = SOAPpy.SOAPProxy('http://localhost:12321')
s.show_gui()
s.set_focus('m__button_two')

If I'm not mistaken, I think you're running into a threading issue. For the most part, you cannot make calls to the GUI's widgets from a separate thread because then you block the main loop and end up with what appears to be a frozen application. In other words, most wxPython methods are NOT threadsafe. There are some easy workarounds though. The easiest in this case is to just use wx.CallAfter and wrap your focus method in that. See the wiki (or the archives) for more info: LongRunningTasks - wxPyWiki

···

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org

__________ Information from ESET NOD32 Antivirus, version of virus signature database 4101 (20090525) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com