I posted this first in Google Groups. Hopefully it is not an annoying cross-post to go here also.
I am trying to understand how ScrolledWindow decides where to position
scrollbars.
The sample code simulates a small piece of our application. In the
application, the panels are actually contained in a notebook within
the scrolled window.
For the sample, I made a simple scrolled window containing a panel
that is bigger than containing window. When you run the application,
the scrollbars are initially positioned to the far right and bottom of
the scrolled window. I want them to be positioned to the left top. I
can make that happen by calling Scroll(0,0) for the scrolled window
after Show() for the frame, but if I click on the window, the
scroll bars reposition to the far right and bottom by themselves.
How can I reliably position the scrollbars to (0,0)?
We maintain the GUI for our application in wxGlade, I have little
flexibility to make major changes in the classes used to build the app
at this time. I can insert code that modifies the behavior of widgets
after the wxGlade generated layout is complete. This sample is a
cleaned up version of code generated by wxGlade.
Here are some tests I have run:
A. with Scroll(0,0) in MyApp.init() commented out
- scrollbars initially positioned to bottom right
- click on title bar or text control, positions scrolled window to
beginning of text box, almost top left
B. with Scroll(0,0) in MyApp.init() active
- scrollbars initially positioned to top left
- click on title bar or text control, positions scrolled window to
bottom right
Here is what I want to have happen:
- Screen should initially position to (0,0)
- Automatically scroll if selecting a control that is not visible on
screen (I think this works, but because of the other problems I can’t
prove it) - As mentioned before, the problem exists for panels contained in a
Notebook. I need the behavior to be consistent for those panels also.
Environment:
Windows XP Service Pack 3
wx 2.8.9.2 - but I am pretty sure same behavior exists on earlier
versions
---------------- sample code starts here
import wx
class MyFrame(wx.Frame):
def init(self, *args, **kwds):
kwds[“style”] = wx.DEFAULT_FRAME_STYLE
wx.Frame.init(self, *args, **kwds)
# main scrolled window
self.scroller = wx.ScrolledWindow(self, -1, style=wx.TAB_TRAVERSAL)
# a panel in the scroller
self.panel = wx.Panel(self.scroller, -1)
self.text = wx.StaticText(self.panel, -1, “tab2 text”)
self.text_ctrl = wx.TextCtrl(self.panel, -1, “”)
self.__set_properties()
self.__do_layout()
def __set_properties(self):
self.SetSize((700, 500))
self.text_ctrl.SetMinSize((800,800))
self.scroller.SetScrollRate(20, 20)
def __do_layout(self):
# layout the panel
sizer_panel = wx.BoxSizer(wx.VERTICAL)
sizer_panel.Add(self.text, 0, wx.EXPAND, 0)
sizer_panel.Add(self.text_ctrl, 1, wx.ALL|wx.EXPAND, 5)
self.panel.SetSizer(sizer_panel)
# layout the scroller
scrollsizer = wx.BoxSizer(wx.HORIZONTAL)
scrollsizer.Add(self.panel, 1, wx.EXPAND, 0)
self.scroller.SetSizer(scrollsizer)
# layout the frame
main_sz = wx.BoxSizer(wx.VERTICAL)
main_sz.Add(self.scroller, 1, wx.EXPAND, 0)
self.SetSizer(main_sz)
main_sz.SetSizeHints(self)
self.Layout()
# end wxGlade
self.SetSize((700,500))
class MyApp(wx.App):
def OnInit(self):
myframe = MyFrame(None, -1, "force scroll to (0,0) [wx:%s]"%wx.version())
myframe.Show()
#myframe.scroller.Scroll(0,0)
self.SetTopWindow(myframe)
return 1
if name == “main”:
app = MyApp(0)
import wx.lib.inspection
wx.lib.inspection.InspectionTool().Show()
app.MainLoop()
···
–
Mike Conley