Search code examples
pythonpython-2.7scrollwxpython

How do I scroll to the bottom of a ScrolledWindow when using a sizer


I am creating a text area in wxpython that needs to be scrollable and dynamically sized. I've borrowed some code, which which works fine except that I don't seem to be able to make use of the ScrolledWindow.Scroll command.

Here's the code:

import wx
class AScrolledWindow(wx.ScrolledWindow):
    def __init__(self, parent):
        self.parent = parent
        wx.ScrolledWindow.__init__(self, parent, -1, style=wx.TAB_TRAVERSAL)
        gb = wx.GridBagSizer(vgap=0, hgap=3)
        self.sizer = gb
        self._labels = []
        for y in xrange(1,30):
            self._labels.append(wx.StaticText(self, -1, "Label #%d" % (y,)))
            gb.Add(self._labels[-1], (y,1), (1,1))
        self.SetSizer(self.sizer)
        fontsz = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT).GetPixelSize()
        self.SetScrollRate(fontsz.x, fontsz.y)
        self.EnableScrolling(True,True)
        self.Scroll(0,100)

class TestFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'Programmatic size change')
        sz = wx.BoxSizer(wx.VERTICAL)
        pa = AScrolledWindow(self)
        sz.Add(pa, 1, wx.EXPAND)
        self.SetSizer(sz)
        pa.Scroll(0,100)

def main():
    wxapp = wx.App()
    fr = TestFrame()
    fr.Show(True)
    wxapp.MainLoop()

if __name__=='__main__':
    main()

I've tested the ScrolledWindow.Scroll command without the sizer and it works, suggesting to me that it doesn't work with the sizer. However there is no mention in the documentation of this effect.


Solution

  • So it seems calling the Scroll method from the init doesn't work. But it does work afterwards. Here's the working code:

    import wx
    class AScrolledWindow(wx.ScrolledWindow):
        def __init__(self, parent):
            self.parent = parent
            wx.ScrolledWindow.__init__(self, parent, -1, style=wx.TAB_TRAVERSAL)
            box = wx.BoxSizer(wx.VERTICAL)
            self.sizer = box
            self._labels = []
            self.button = wx.Button(self, -1, "Scroll Me")
            box.Add(self.button)
            self.Bind(wx.EVT_BUTTON,  self.OnClickTop, self.button)
            for y in xrange(1,30):
                self._labels.append(wx.StaticText(self, -1, "Label #%d" % (y,)))
                box.Add(self._labels[-1])
            self.SetSizer(self.sizer)
            fontsz = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT).GetPixelSize()
            self.SetScrollRate(fontsz.x, fontsz.y)
            self.EnableScrolling(True,True)
    
        def OnClickTop(self, event):
            self.Scroll(0, 50)
    
    class TestFrame(wx.Frame):
        def __init__(self):
            wx.Frame.__init__(self, None, -1, 'Programmatic size change')
            sz = wx.BoxSizer(wx.VERTICAL)
            self.ascrolledwindow = AScrolledWindow(self)
            sz.Add(self.ascrolledwindow, 1, wx.EXPAND)
            self.SetSizer(sz)
    
    
    def main():
        wxapp = wx.App()
        fr = TestFrame()
        fr.Show(True)
        fr.ascrolledwindow.Scroll(0,50)
        wxapp.MainLoop()
    
    if __name__=='__main__':
        main()