wx.ScrolledWindow with wx.TextCtrl

Examples of wx.ScrolledWindow with some TextCtrl.

It is necessary to have a wx.ScrolledWindow or a wx.PyScrolledWindow be managed by a sizer to gaurantee that the scrollbars appear when they are needed.

The first example shows the basic way. When the focus goes to a TextCtrl the scrollbars do not move automatically.

The second example moves the scrollbars when the focus goes to the control. This moves the TextCtrl in focus to the top-left of the Frame. It alse uses a wx.FlexGridSizer to efficiently arrange the controls.

First example, basic

Thanks to Gary Simmons for clarifying my code.

   1 #!/usr/bin/python
   2 
   3 import wx
   4 
   5 class FicheFrame( wx.Frame ) :
   6 
   7     def __init__( self ) :
   8 
   9         wx.Frame.__init__( self, None,-1, "FicheFrame", size=(300, 400) )
  10 
  11         scrollWin = wx.PyScrolledWindow( self, -1 )
  12 
  13         x = 20       # Magic numbers !?
  14         y = 20
  15         for i in range( 50 ) :
  16 
  17             txtStr = " Text %02d  : " % (i+1)
  18             stTxt = wx.StaticText( scrollWin, -1, txtStr, pos=(x, y) )
  19 
  20             w, h = stTxt.GetSize()
  21             txtCtrl = wx.TextCtrl( scrollWin, -1, pos=(x+w+5, y) )
  22 
  23             dy = h + 10     # calculate for next loop
  24             y += dy
  25 
  26         #end for
  27 
  28         scrollWin.SetScrollbars( 0, dy,  0, y/dy+1 )
  29         scrollWin.SetScrollRate( 1, 1 )      # Pixels per scroll increment
  30 
  31     #end __init__ def
  32 
  33 #end class
  34 
  35 if __name__ == '__main__' :
  36 
  37     myapp = wx.App( redirect=False )
  38 
  39     myAppFrame = FicheFrame()
  40     myAppFrame.Show()
  41 
  42     myapp.MainLoop()

Second example: managed TextCtrl focus

This example moves the scrollbars automatically when the focus goes to a TextCtrl. The comments describe when this happens. Multi-line TextCtrl's can be substituted.

   1 #!/usr/bin/python
   2 
   3 import wx
   4 
   5 class FicheFrameWithFocus( wx.Frame ) :
   6 
   7     def __init__( self ) :
   8 
   9         wx.Frame.__init__( self, None, -1 ,"FicheFrameWithFocus", size=(275, 500) )
  10 
  11         self.scroll = wx.ScrolledWindow( self, -1 )
  12 
  13         self.frmPanel = wx.Panel( self.scroll, -1 )
  14 
  15         # A sizer allows the horizontal scrollbar to appear when needed.
  16         flGrSzr = wx.FlexGridSizer( 50, 2, 2, 2 )   # rows, cols, hgap, vgap
  17 
  18         for i in range( 50 ) :
  19 
  20             textStr = " Champ (txt) %2d  : " % (i+1)
  21             flGrSzr.Add( wx.StaticText( self.frmPanel, -1, textStr ) )
  22 
  23             txtCtrl = wx.TextCtrl( self.frmPanel, -1, size=(100, -1), style=0 )
  24             wx.EVT_SET_FOCUS( txtCtrl, self.OnFocus )
  25             flGrSzr.Add( txtCtrl )
  26 
  27         #end for
  28 
  29         # Create a border around frmPnlSizer to the edges of the frame.
  30         frmPnlSizer = wx.BoxSizer( wx.VERTICAL )
  31         frmPnlSizer.Add( flGrSzr, proportion=1, flag=wx.ALL, border=20 )
  32 
  33         self.frmPanel.SetSizer( frmPnlSizer )
  34         self.frmPanel.SetAutoLayout( True )
  35         self.frmPanel.Layout()
  36         self.frmPanel.Fit()     # frmPnlSizer borders will be respected
  37 
  38         self.Center()
  39         self.MakeModal( True )
  40 
  41         # Scrolling parameters must be set AFTER all controls have been laid out.
  42         self.frmPanelWid, self.frmPanelHgt = self.frmPanel.GetSize()
  43         self.unit = 1
  44         self.scroll.SetScrollbars( self.unit, self.unit, self.frmPanelWid/self.unit, self.frmPanelHgt/self.unit )
  45 
  46     #end __init__ def
  47 
  48     def OnFocus( self, event ) :
  49         """
  50         This makes the selected (the one in focus) textCtrl to be automatically
  51         repositioned to the top-left of the window. One of the scrollbars
  52         must have been moved for this to happen.
  53 
  54         The benefits for doing this are dubious. but this demonstrates how it can be done.
  55         """
  56 
  57         parentControl = self.FindWindowById( event.GetId() )  # The parent container control
  58         parentPosX, parentPosY = parentControl.GetPosition()
  59         hx, hy = parentControl.GetSizeTuple()
  60         clientSizeX, clientSizeY = self.scroll.GetClientSize()
  61 
  62         sx, sy = self.scroll.GetViewStart()
  63         magicNumber = 20        # Where did this value come from ?!
  64         sx = sx * magicNumber
  65         sy = sy * magicNumber
  66 
  67         if (parentPosY < sy ) :
  68             self.scroll.Scroll( 0, parentPosY/self.unit )
  69 
  70         if ( parentPosX < sx ) :
  71              self.scroll.Scroll( 0, -1 )
  72 
  73         if (parentPosX + sx) > clientSizeX  :
  74             self.scroll.Scroll( 0, -1 )
  75 
  76         if (parentPosY + hy - sy) > clientSizeY :
  77             self.scroll.Scroll( 0, parentPosY/self.unit )
  78 
  79     #end OnFocus def
  80 
  81 #end FicheFrameWithFocus class
  82 
  83 if __name__ == '__main__' :
  84 
  85     myapp = wx.App( redirect=False )
  86     appFrame = FicheFrameWithFocus()
  87     appFrame.Show()
  88     myapp.MainLoop()

ScrolledWindows (last edited 2011-07-04 18:47:18 by WinCrazy)