dialog, TextCtrl subclassing by using xrc

120 views
Skip to first unread message

Cookie

unread,
Jul 18, 2009, 4:16:50 AM7/18/09
to wxPython-users
Hi, all
I have been trying to use xrc and subclassing.
Surely, I read TwoStageCreation, SubclassingListCtrlWithXrc.


code is here:
####################################################
# -*- coding: utf-8 -*-

import sys
import os
import wx
from wx import xrc


#global
_firstEventType = wx.EVT_SHOW


menculator_xrc = '''\
<?xml version="1.0" ?><resource>
<object class="wxDialog" name="mainframe"
subclass="menculator.MCDialog">
<object class="wxBoxSizer">
<orient>wxVERTICAL</orient>
<object class="sizeritem">
<object class="wxBoxSizer">
<orient>wxVERTICAL</orient>
<object class="sizeritem">
<object class="wxStaticText" name="qSText"/>
<option>1</option>
<flag>wxALL|wxEXPAND</flag>
</object>
<object class="sizeritem">
<object class="wxTextCtrl" name="aTCtrl"
subclass="menculator.MyTextCtrl"/>
<option>1</option>
<flag>wxALL|wxEXPAND</flag>
</object>
</object>
<option>1</option>
<flag>wxALL|wxEXPAND</flag>
<border>5</border>
</object>
</object>
<object class="wxMenuBar"/>
<title>mainframe</title>
<style>wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</style>
</object>
</resource>'''


class MyTextCtrl( wx.TextCtrl ):
def __init__( self , parent ):
pre = wx.PreTextCtrl()
self.PostCreate( pre )
self.Bind( _firstEventType , self.OnCreate )

def OnCreate():
self.Unbind(self._firstEventType)
self.Refresh()

self.Bind( wx.EVT_KEY_UP , self.OnKeyUp )

def OnKeyUp( self , event ):
if self.aTCtrl == self.dlg.FindFocus():
if wx.WXK_RETURN == event.GetKeyCode():
event


class MCDialog( wx.Dialog ):
def __init__( self ):
pre = wx.PreDialog()
global xmlRes
xmlRes.LoadOnDialog( pre , None , "mainframe" )
self.PostCreate( pre )
self.Bind( _firstEventType , self.OnCreate )

def OnCreate( self , event ):
self.Unbind( _firstEventType )
self.Refresh()

self.qSText = self.FindWindowById( xrc.XRCID( 'qSText' ) )
self.aTCtrl = self.FindWindowById( xrc.XRCID( 'aTCtrl' ) )



class Mencualtor( wx.App ):
def __init__( self ):
wx.App.__init__( self , False )


def OnInit( self ):
global xmlRes
menculator_xrc
xmlRes = xrc.EmptyXmlResource()
xmlRes.LoadFromString( menculator_xrc )
return True





def main():
app = Mencualtor()
dlg = MCDialog()
dlg.Show()
app.MainLoop()



main()
####################################################




wx.Dialog, wx.TextCtrl are subclassed, problem is don't created
'aTCtrl'.
after run, error message box shows "Subclass 'menculator.MyTextCtrl'
not found for resource 'aTCtrl', not subclassing!"
I tested LoadDialog function that create child widgets against
LoadOnDialog.
how do i solve it?


============================================
sorry about my poor english

Hong Yuan

unread,
Jul 20, 2009, 5:15:05 PM7/20/09
to wxPython-users
> ####################################################
>
> wx.Dialog, wx.TextCtrl are subclassed, problem is don't created
> 'aTCtrl'.
> after run, error message box shows "Subclass 'menculator.MyTextCtrl'
> not found for resource 'aTCtrl', not subclassing!"
> I tested LoadDialog function that create child widgets against
> LoadOnDialog.
> how do i solve it?
>
> ============================================
> sorry about my poor english

You made in your code a bunch of careless mistakes. Try use pylint to
check the code and you will find out many clues. Primary problem is:

class MyTextCtrl( wx.TextCtrl ):
def __init__( self , parent ):

There should not be the parent argument since XRC mechanism is not
supplying it.

Also:

def OnCreate():
self.Unbind(self._firstEventType)

self._firstEventType is not defined.

And I think you'd better bind to EVT_WINDOW_CREATE instead of EVT_SHOW
for widget creation, since the EVT_SHOW will be invoked only when the
control is displayed, not when it is created.

Attached is a slightly modified version that is working:

# -*- coding: utf-8 -*-

import sys
import os
import wx
from wx import xrc

def __init__( self ):
pre = wx.PreTextCtrl()
self.PostCreate( pre )
self.Bind(wx.EVT_WINDOW_CREATE, self.OnCreate)

def OnCreate( self, event):
if self is event.GetEventObject():
self.Bind( wx.EVT_KEY_UP , self.OnKeyUp )
event.Skip()

def OnKeyUp( self , event ):
if self.aTCtrl == self.dlg.FindFocus():
if wx.WXK_RETURN == event.GetKeyCode():
event

class MCDialog( wx.Dialog ):
def __init__( self ):
pre = wx.PreDialog()
self.PostCreate( pre )
self.Bind(wx.EVT_WINDOW_CREATE, self.OnCreate)

def OnCreate( self , event ):
if self is event.GetEventObject():
self.qSText = self.FindWindowById( xrc.XRCID( 'qSText' ) )
self.aTCtrl = self.FindWindowById( xrc.XRCID( 'aTCtrl' ) )
event.Skip()


class Mencualtor( wx.App ):
def __init__( self ):
wx.App.__init__( self , False )

def OnInit( self ):
global xmlRes
menculator_xrc
xmlRes = xrc.EmptyXmlResource()
xmlRes.LoadFromString( menculator_xrc )

dlg = xmlRes.LoadDialog(None, 'mainframe')
dlg.Show()

return True

def main():
app = Mencualtor()
app.MainLoop()

if __name__ == '__main__':
main()

Robin Dunn

unread,
Jul 20, 2009, 5:41:46 PM7/20/09
to wxPytho...@googlegroups.com
Cookie wrote:
> Hi, all
> I have been trying to use xrc and subclassing.
> Surely, I read TwoStageCreation, SubclassingListCtrlWithXrc.
>
>

>

> wx.Dialog, wx.TextCtrl are subclassed, problem is don't created
> 'aTCtrl'.
> after run, error message box shows "Subclass 'menculator.MyTextCtrl'
> not found for resource 'aTCtrl', not subclassing!"
> I tested LoadDialog function that create child widgets against
> LoadOnDialog.
> how do i solve it?

You have some problems:

1. The subclassing factory works by importing the module where the class
resides. Since this is the same as your main script in this case you
need to be sure to protect the call to main() so it is not executed
again when XRC imports the module:

if __name__ == '__main__':
main()

2. When XRC creates an instance of the class specified in the subclass
attribute it calls it with no parameters. Your sample has
MyTextCtrl.__init__ expecting a parent parameter.

3. self._firstEventType does not exist.

4. Not really a problem per se, but not really a good approach to take:
You've got MCDialog loading itself from the XRC, but it is also using
the subclass attribute in the XRC. IMO you should choose one or the
other approach, not both.


--
Robin Dunn
Software Craftsman
http://wxPython.org

Cookie

unread,
Jul 23, 2009, 3:41:38 AM7/23/09
to wxPython-users
Thanks, all
I solve the problem on the strength of you.

> 4. Not really a problem per se, but not really a good approach to take:
>   You've got MCDialog loading itself from the XRC, but it is also using
> the subclass attribute in the XRC.  IMO you should choose one or the
> other approach, not both.

You mean that

...
class Mencualtor( wx.App ):
...
def OnInit( self ):
...
self.frame = xmlRes.LoadDialog( None , 'mainframe' )
...

def main():
app = Mencualtor()
app.MainLoop()



right?
Message has been deleted

Yoel Koenka

unread,
Sep 19, 2013, 3:12:41 AM9/19/13
to wxpytho...@googlegroups.com, wxPython-users
Hi Cookie,
I know this is kind of old, but could you please post your fixed code?
I'm trying to find an example for subclassing masked.NumCtrl with XRCed but didn't find it by now.

Thanks,
Joel
Reply all
Reply to author
Forward
0 new messages