Disablling scrolling of a scroll bar while keeping it visible in wxPython
Question: I am currently working with wxPython v3.0, python v2.7 on Windows 7 OS. I have
question regarding the scroll bars. In my application I have a GUI which has
many scrolled panels. The scroll bar of these scrolled panels are working fine
too.

**Problem:** My question is that is it possible to disable the scrolling of a
scroll bar while keeping it visible on a particular scrolled panel? _The
scroll bar shouldn't scroll when being clicked on the scroll buttons or by
dragging the scroll bar_.

I know that we can disable horizontal or vertical scrolling by using
`SetupScrolling(scroll_y=False)` and `SetupScrolling(scroll_x=False)`. But
this will also make the scroll bar invisible. I also tried setting the scroll
rate to 0 by using `rate_y` & `rate_x`, this also makes the scroll bar
invisible. In short I want to show the scroll bar but make it do nothing.

Is there a way to capture the scroll events and make them to do nothing? I
tried a hit and trial method by binding `myPanel` with
[wx.EVT_SCROLLWIN](http://wxpython.org/Phoenix/docs/html/ScrollWinEvent.html#scrollwinevent)
to execute a function that does nothing. Unfortunately it didn't worked (the
scroll bar is still scrolling).

    
    
    myPanel = wx.lib.scrolledpanel.ScrolledPanel(self, -1, style=wx.SIMPLE_BORDER)
    myPanel.Bind(wx.EVT_SCROLLWIN, self.onScroll)
    
    def onScroll(self, event):
        pass
    

Here is a quick & dirty code sample to play around and can be [downloaded
too](https://db.tt/wQK3FDhd)! to avoid identation errors.:

    
    
    #!/usr/bin/env python
    
    import wx
    import wx.lib.scrolledpanel
    
    
    class GUI(wx.Frame):
    
         def __init__(self, parent, id, title):
             screenSize = (400, 400)
             wx.Frame.__init__(self, None, id, title, size=screenSize)
             myFont = wx.Font(15, wx.MODERN, wx.NORMAL, wx.BOLD)
             panelsSizer = wx.BoxSizer(wx.VERTICAL)
             sizer1 = wx.BoxSizer(wx.VERTICAL)
             myPanel = wx.lib.scrolledpanel.ScrolledPanel(self, -1,style=wx.SIMPLE_BORDER)
             myPanel.Bind(wx.EVT_SCROLLWIN, self.onScroll)
             myPanel.SetupScrolling()
             panel1 = wx.lib.scrolledpanel.ScrolledPanel(myPanel, -1, style=wx.SIMPLE_BORDER)
             panel1.SetBackgroundColour('#FFFFFF')
             panel2 = wx.lib.scrolledpanel.ScrolledPanel(myPanel, -1, style=wx.SIMPLE_BORDER)
             panel2.SetBackgroundColour('#55F4FF')
    
    
             k = 0
             for i in range(1,7):
                 sPanel ='Panel' +str(k)
                 sPanel = wx.Panel(panel1)
                 label = str(k)+'This is panel-1'
                 text = wx.StaticText(sPanel, -1, label)
                 text.SetForegroundColour('#0101DF')
                 text.SetFont(myFont)
                 sizer1.Add(sPanel, 0, wx.ALL, 5)
                 sizer1.Add(wx.StaticLine(panel1), 0, wx.ALL|wx.EXPAND, 0)
                 k += 1
    
             panel1.SetSizer(sizer1)
             panelsSizer.Add(panel1, 1, wx.EXPAND)
             panelsSizer.Add(panel2, 1, wx.EXPAND)
             myPanel.SetSizer(panelsSizer)
    
         def onScroll(self, event):
                pass
    
    
    if __name__=='__main__':
        app = wx.App()
        frame = GUI(parent=None, id=-1, title="Test")
        frame.Show()
        app.MainLoop()
    

Any suggestion? Thank you for your time.


Answer: Woo hoo, I read you solved it.

Meanwhile, this is the best awful hack I could come up with:

    
    
    #!/usr/bin/env python
    
    import wx
    import wx.lib.scrolledpanel
    
    
    class GUI(wx.Frame):
    
         def __init__(self, parent, id, title):
             screenSize = (400, 400)
             wx.Frame.__init__(self, None, id, title, size=screenSize)
             myFont = wx.Font(15, wx.MODERN, wx.NORMAL, wx.BOLD)
             panelsSizer = wx.BoxSizer(wx.VERTICAL)
             sizer1 = wx.BoxSizer(wx.VERTICAL)
             myPanel = wx.lib.scrolledpanel.ScrolledPanel(self, -1,style=wx.SIMPLE_BORDER)
             myPanel.Bind(wx.EVT_SCROLLWIN, self.onScroll)
             myPanel.SetupScrolling()
             panel1 = wx.lib.scrolledpanel.ScrolledPanel(myPanel, -1, style=wx.SIMPLE_BORDER)
             panel1.SetBackgroundColour('#FFFFFF')
             panel2 = wx.lib.scrolledpanel.ScrolledPanel(myPanel, -1, style=wx.SIMPLE_BORDER)
             panel2.SetBackgroundColour('#55F4FF')
    
    
             k = 0
             for i in range(1,7):
                 sPanel ='Panel' +str(k)
                 sPanel = wx.Panel(panel1)
                 label = str(k)+'This is panel-1'
                 text = wx.StaticText(sPanel, -1, label)
                 text.SetForegroundColour('#0101DF')
                 text.SetFont(myFont)
                 sizer1.Add(sPanel, 0, wx.ALL, 5)
                 sizer1.Add(wx.StaticLine(panel1), 0, wx.ALL|wx.EXPAND, 0)
                 k += 1
    
             panel1.SetSizer(sizer1)
             panelsSizer.Add(panel1, 1, wx.EXPAND)
             panelsSizer.Add(panel2, 1, wx.EXPAND)
             myPanel.SetSizer(panelsSizer)
             self.scrolled_panel=myPanel 
    
         def onScroll(self, event):
            print "scroll event"
            for child in self.scrolled_panel.GetChildren():
               try:  
                  child.SetThumbPosition(0)
                  print "set child"
               except:
                  print "oops,probably not a scrollbar :) "
    
    
    if __name__=='__main__':
        app = wx.App()
        frame = GUI(parent=None, id=-1, title="Test")
        frame.Show()
        app.MainLoop()
    

It doesn't stop them dragging the scrollbar, but it does pop it back after
they let go.

**Update: The code above only works on OSX, not Windows.**

Under OSX, the children of a ScrolledPanel are reported as:

    
    
    wxWindowList: [<wx._controls.ScrollBar; proxy of <Swig Object of type 'wxScrollBar *' at 0x10068f830> >, <wx._controls.ScrollBar; proxy of <Swig Object of type 'wxScrollBar *' at 0x100691230> >, <wx._core.Window; proxy of <Swig Object of type 'wxWindow *' at 0x100691d20> >, <wx.lib.scrolledpanel.ScrolledPanel; proxy of <Swig Object of type 'wxPyScrolledWindow *' at 0x1004ac990> >, <wx.lib.scrolledpanel.ScrolledPanel; proxy of <Swig Object of type 'wxPyScrolledWindow *' at 0x1004af8e0> >]
    

It's the two ScrollBar's that my hack is targetting.

Under Windows, the same call returns:

    
    
    wxWindowList: [<wx.lib.scrolledpanel.ScrolledPanel; proxy of <Swig Object of type 'wxPyScrolledWindo
    w *' at 0x26837b8> >, <wx.lib.scrolledpanel.ScrolledPanel; proxy of <Swig Object of type 'wxPyScroll
    edWindow *' at 0x26839b0> >]
    

This is much harder to understand. Where are the scroll bars hiding? I guess
this is what you get for hacking into components that are supposed to be
encapsulated for you :)

