[wxPython] Mysterious focus behaviour on wxGTK

Hi All,

While using wxPython 2.2.2 on top of wxWindows/GTK 2.2.2 I encountered
strange focus behaviour in dialogs. It seems that SetFocus() method
has no effect for some child controls. The attached program illustrates
this for dialog containing one instance of wxTextCtrl and one instance
of wxComboBox. The "self.cb1.SetFocus()" line (emphasized by
appropriate comments) has no effect on wxGTK (it works as expected on
Windows). Strangely enough, it works OK for two wxTextCtrls, but not
for two wxComboBoxes.

(Note: you need to click somewhere inside the program main frame
client area for dialog to appear)

···

--
Olwi

----------------------- FocusProblem.py ------------------------------
#!/usr/bin/env python

from wxPython import wx

OK = wx.TRUE
YES = wx.TRUE
NO = wx.FALSE

OK_DEFAULT = 1
CANCEL_DEFAULT = 2

class SimpleDialog ( wx.wxDialog ):
    """"""

    def __init__ ( self, parent, id=-1, title="Simple Dialog", okTitle = "OK", cancelTitle = "Cancel", default = OK_DEFAULT ):
        """"""
        wx.wxDialog.__init__( self, parent, id, title )

        # Create all the child controls
        topSizer = wx.wxBoxSizer( wx.wxVERTICAL )
        self.Body( topSizer )
        self.Buttons( topSizer, okTitle, cancelTitle, default )
        wx.EVT_BUTTON( self, wx.wxID_OK, self.OnOK_Validate )

        # Calculate dialog layout
        self.SetAutoLayout( YES )
        self.SetSizer( topSizer )
        topSizer.Fit( self )
        topSizer.SetSizeHints( self )
        #self.Layout()

        # Load initial values to child controls (and possibly set/modify initial focus)
        self.SetInitialValues()
        
    def Body ( self, topSizer ):
        """Create dialog body by creating and placing necessary child controls"""

    def Buttons ( self, topSizer, okTitle, cancelTitle, default ):
        """Create standard dialog OK/Cancel or similar buttons"""
        buttonsBox = wx.wxBoxSizer( wx.wxHORIZONTAL )
        bOK = wx.wxButton( self, wx.wxID_OK, okTitle )
        bCancel = wx.wxButton( self, wx.wxID_CANCEL, cancelTitle )
        buttonsBox.Add( bOK, 0, wx.wxALL, 10 )
        buttonsBox.Add( bCancel, 0, wx.wxALL, 10 )
        if default == OK_DEFAULT:
            bOK.SetDefault()
        elif default == CANCEL_DEFAULT:
            bCancel.SelDefault()
        topSizer.Add( buttonsBox, 0, wx.wxALIGN_CENTER )

    def SetInitialValues( self ):
        """Sets initial values of child controls"""

    def RetrieveAndValidate ( self ):
        """Retrieve and validate child controls values. Return validation status (OK/ERROR)"""
        return OK

    def OnOK_Validate ( self, event ):
        ""
        self.RetrieveAndValidate() and event.Skip()

class MyDialog ( SimpleDialog ):
    """"""
    def __init__ ( self, parent, id, title ):
        """"""
        SimpleDialog.__init__( self, parent, id, title )

    def Body ( self, topSizer ):
        vPad = 5; textxSize = 200

        if wx.wxPlatform == "__WXMSW__":
            vals = [ "", "On wxWindows/MSWin focus will be here (this is OK)", "" ]
        else:
            vals = [ "On wxWindows/GTK focus will be here (but it shouldn't!)", "" ]

        fgs = wx.wxFlexGridSizer( 0, 2 )

        label = wx.wxStaticText( self, -1, "wxTextCtrl: " )
        fgs.Add( label, 0, wx.wxALIGN_RIGHT | wx.wxALIGN_CENTER_VERTICAL )
        self.tc1 = wx.wxTextCtrl( self, -1, vals[0], wx.wxDefaultPosition, wx.wxDLG_SZE( self, wx.wxSize(textxSize,-1) ) )
        fgs.Add( self.tc1 )
        fgs.Add( 1, vPad ); fgs.Add( 1, vPad )

        label = wx.wxStaticText( self, -1, "wxComboBox: " )
        fgs.Add( label, 0, wx.wxALIGN_RIGHT | wx.wxALIGN_CENTER_VERTICAL )
        self.cb1 = wx.wxComboBox( self, -1, vals[1], wx.wxDefaultPosition, wx.wxDLG_SZE( self, wx.wxSize(textxSize,-1) ) )
        fgs.Add( self.cb1 )
        fgs.Add( 1, vPad ); fgs.Add( 1, vPad )

        topSizer.Add( fgs, 0, wx.wxALIGN_CENTER | wx.wxTOP | wx.wxLEFT | wx.wxRIGHT, 10 )

        ### This doesn't work properly on wxGTK !!!
        self.cb1.SetFocus()
        ### This doesn't work properly on wxGTK !!!

class TopFrame ( wx.wxFrame ):

    def __init__ ( self ):
        wx.wxFrame.__init__( self, wx.NULL, -1, "Dialog testing app" )
        wx.EVT_LEFT_UP( self, self.OnClick )
        wx.EVT_RIGHT_UP( self, self.OnClick )

    def OnClick ( self, event ):
        dialog = MyDialog( self, -1, "Test dialog" )
        dialog.ShowModal()
        dialog.Destroy()
        
class DialogApp ( wx.wxApp ):

    def OnInit ( self ):
        frame = TopFrame()
        frame.Show( YES )
        self.SetTopWindow( frame )
        return OK

app = DialogApp( 0 )
app.MainLoop()
----------------------- FocusProblem.py ------------------------------

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/mailman/listinfo/wxpython-users