This is interesting. I played with your code for a bit and it seems that when onCreate() is called, only the frame has been created and it has no child windows (self.GetChildren() returns an empty list).
It can be handled by using a wx.CallAfter call like this :
···
---------------------------------
class MyBrokenFrame(wx.Frame):
def __init__(self):
pre = wx.PreFrame()
# XRC will do the Create
self.PostCreate(pre)
self.Bind(wx.EVT_WINDOW_CREATE, self.onCreate, self)
def postCreate(self):
print 'button1:', xrc.XRCCTRL(self, 'Button1')
print 'button2:', xrc.XRCCTRL(self, 'Button2')
def onCreate(self, evt):
self.Unbind(wx.EVT_WINDOW_CREATE)
self.Fit()
wx.CallAfter(self.postCreate)
---------------------------------
It seems that both LoadFrame and LoadOnFrame fire the EVT_WINDOW_CREATE event. In MyFrame you try to access the buttons after LoadOnFrame has returned and so all the controls are already available. In MyBrokenFrame the code that runs in onCreate runs before LoadFrame has completed, actually LoadFrame fires the EVT_WINDOW_CREATE and therefore calls your onCreate function before the other controls are created.
I don't see why would you want to use the subclassing facility of XRC when creating frames. You can just use the scheme in MyFrame and MyApp and add all the functionality you want to MyFrame.
Hope I helped you a bit..
Eli.
----- Original Message ----- From: "anjin84" <anjin84@gmail.com>
To: <wxPython-users@lists.wxwidgets.org>
Sent: Wednesday, March 08, 2006 12:16 AM
Subject: [wxPython-users] XRC subclasses accessing XRC elements
I cannot access controls from within a derived class.
Is this a limitation of XRC or is there an elegant way to do this?
Perhaps I'm just misunderstanding the subclassing concept.
Here is a contrived example...
Notice that MyFrame is created by loading the frame onto the
'PreFrame' element, whereas MyBrokenFrame is created using xrc's
LoadFrame function where MyBrokenFrame is specified as a subclass.
From within MyBrokenFrame I'm not able to get access to the buttons.
To switch between the two simply change app = MyBrokenApp() to app = MyApp().
----------------------- BEGIN tmp.xrc ---------------------------
<?xml version="1.0" encoding="cp1252"?>
<resource>
<object class="wxFrame" name="MainFrame2" subclass="tmp.MyBrokenFrame">
<title></title>
<object class="wxBoxSizer">
<orient>wxVERTICAL</orient>
<object class="sizeritem">
<object class="wxPanel" name="Panel1">
<object class="wxButton" name="Button1">
<label>Button1</label>
</object>
</object>
</object>
<object class="sizeritem">
<object class="wxPanel" name="Panel2">
<object class="wxButton" name="Button2">
<label>Button2</label>
</object>
</object>
</object>
</object>
</object>
<object class="wxFrame" name="MainFrame">
<title></title>
<object class="wxBoxSizer">
<orient>wxVERTICAL</orient>
<object class="sizeritem">
<object class="wxPanel" name="Panel1">
<object class="wxButton" name="Button1">
<label>Button1</label>
</object>
</object>
</object>
<object class="sizeritem">
<object class="wxPanel" name="Panel2">
<object class="wxButton" name="Button2">
<label>Button2</label>
</object>
</object>
</object>
</object>
</object>
</resource>
-------------------- END tmp.xrc -----------------------
-------------------- BEGIN tmp.py ---------------------
import wx
import wx.xrc as xrc
GUI_FILE = 'tmp.xrc'
class MyApp(wx.App):
def OnInit(self):
self.res = xrc.XmlResource(GUI_FILE)
self.frame = MyFrame(None, self.res)
self.SetTopWindow(self.frame)
self.frame.Show(True)
return True
class MyFrame(wx.Frame):
def __init__(self, parent, resource):
self.res = resource
pre = wx.PreFrame()
self.res.LoadOnFrame(pre, parent, 'MainFrame')
self.PostCreate(pre)
print 'button1:', xrc.XRCCTRL(self, 'Button1')
print 'button2:', xrc.XRCCTRL(self, 'Button2')
class MyBrokenApp(wx.App):
def OnInit(self):
self.res = xrc.XmlResource(GUI_FILE)
self.frame = self.res.LoadFrame(None, 'MainFrame2')
self.SetTopWindow(self.frame)
self.frame.Show(True)
return True
class MyBrokenFrame(wx.Frame):
def __init__(self):
pre = wx.PreFrame()
# XRC will do the Create
self.PostCreate(pre)
self.Bind(wx.EVT_WINDOW_CREATE, self.onCreate)
def onCreate(self, evt):
self.Unbind(wx.EVT_WINDOW_CREATE)
self.Fit()
print 'button1:', xrc.XRCCTRL(self, 'Button1')
print 'button2:', xrc.XRCCTRL(self, 'Button2')
if __name__ == '__main__':
app = MyBrokenApp()
app.MainLoop()
----------------------- END tmp.py ----------------------
---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org