Scrolling wx.ScrolledPanel with the mouse wheel, arrow keys, and PgUp/PgDn buttons

Hello everyone,

I have a problem:
In my wxPython application I've created a wx.ScrolledPanel, in which
there is a big wx.StaticBitmap that needs to be scrolled.

The scroll bars do appear and I can scroll with them, but I'd also
like to be able to scroll with the mouse wheel and the arrow keys on
the keyboard. It would also be nice if the "Home", "Page Up", and
those other keys would function as expected.

I noticed that the mouse wheel does work when I place a wx.TextCtrl
inside the ScrolledPanel and focus on it. I guess this has something
to do with the focus.

So what do I do?

Thanks,
Ram.

Anyone has a clue?

···

On Jul 19, 12:23 am, cool-RR <ram.rac...@gmail.com> wrote:

Hello everyone,

I have a problem:
In my wxPython application I've created a wx.ScrolledPanel, in which
there is a big wx.StaticBitmap that needs to be scrolled.

The scroll bars do appear and I can scroll with them, but I'd also
like to be able to scroll with the mouse wheel and the arrow keys on
the keyboard. It would also be nice if the "Home", "Page Up", and
those other keys would function as expected.

I noticed that the mouse wheel does work when I place a wx.TextCtrl
inside the ScrolledPanel and focus on it. I guess this has something
to do with the focus.

So what do I do?

Thanks,
Ram.

cool-RR wrote:

Anyone has a clue?

Hello everyone,

I have a problem:
In my wxPython application I've created a wx.ScrolledPanel, in which
there is a big wx.StaticBitmap that needs to be scrolled.

The scroll bars do appear and I can scroll with them, but I'd also
like to be able to scroll with the mouse wheel and the arrow keys on
the keyboard. It would also be nice if the "Home", "Page Up", and
those other keys would function as expected.

I noticed that the mouse wheel does work when I place a wx.TextCtrl
inside the ScrolledPanel and focus on it. I guess this has something
to do with the focus.

So what do I do?

Thanks,
Ram.
    

>

for the middle mouse, check out the wx.lib.dragscroller and bind it to
the appropriate events
for home and end you'll have to do some calculations in relation to the
bitmap's size on the canvas

···

On Jul 19, 12:23 am, cool-RR <ram.rac...@gmail.com> wrote:

Is this necessary? I see that ScrolledPanel already has the
functionality to support the mouse wheel, the problem is that it's
only being used when there is a text control in it. Can't I make it
work without a text control?

···

On Jul 20, 12:29 am, Steven Sproat <spro...@gmail.com> wrote:

cool-RR wrote:
> Anyone has a clue?

> On Jul 19, 12:23 am, cool-RR <ram.rac...@gmail.com> wrote:

>> Hello everyone,

>> I have a problem:
>> In my wxPython application I've created a wx.ScrolledPanel, in which
>> there is a big wx.StaticBitmap that needs to be scrolled.

>> The scroll bars do appear and I can scroll with them, but I'd also
>> like to be able to scroll with the mouse wheel and the arrow keys on
>> the keyboard. It would also be nice if the "Home", "Page Up", and
>> those other keys would function as expected.

>> I noticed that the mouse wheel does work when I place a wx.TextCtrl
>> inside the ScrolledPanel and focus on it. I guess this has something
>> to do with the focus.

>> So what do I do?

>> Thanks,
>> Ram.

for the middle mouse, check out the wx.lib.dragscroller and bind it to
the appropriate events
for home and end you'll have to do some calculations in relation to the
bitmap's size on the canvas

Here is a code sample that demonstrates this behavior:

···

##################################

import wx, wx.lib.scrolledpanel

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        scrolled_panel = \
            wx.lib.scrolledpanel.ScrolledPanel(parent=self, id=-1)
        scrolled_panel.SetupScrolling()

        text = "Ooga booga\n" * 50
        static_text=wx.StaticText(scrolled_panel, -1, text)
        sizer=wx.BoxSizer(wx.VERTICAL)
        sizer.Add(static_text, wx.EXPAND, 0)

        # Uncomment the following 2 lines to see how adding
        # a text control to the scrolled panel makes the
        # mouse wheel work.
        #
        #text_control=wx.TextCtrl(scrolled_panel, -1)
        #sizer.Add(text_control, wx.EXPAND, 0)

        scrolled_panel.SetSizer(sizer)

        self.Show()

if __name__=="__main__":
    app = wx.PySimpleApp()
    my_frame=MyFrame(None, -1)
    #import cProfile; cProfile.run("app.MainLoop()")
    app.MainLoop()

######################################

On Jul 20, 1:16 am, cool-RR <ram.rac...@gmail.com> wrote:

Is this necessary? I see that ScrolledPanel already has the
functionality to support the mouse wheel, the problem is that it's
only being used when there is a text control in it. Can't I make it
work without a text control?

On Jul 20, 12:29 am, Steven Sproat <spro...@gmail.com> wrote:

> cool-RR wrote:
> > Anyone has a clue?

> > On Jul 19, 12:23 am, cool-RR <ram.rac...@gmail.com> wrote:

> >> Hello everyone,

> >> I have a problem:
> >> In my wxPython application I've created a wx.ScrolledPanel, in which
> >> there is a big wx.StaticBitmap that needs to be scrolled.

> >> The scroll bars do appear and I can scroll with them, but I'd also
> >> like to be able to scroll with the mouse wheel and the arrow keys on
> >> the keyboard. It would also be nice if the "Home", "Page Up", and
> >> those other keys would function as expected.

> >> I noticed that the mouse wheel does work when I place a wx.TextCtrl
> >> inside the ScrolledPanel and focus on it. I guess this has something
> >> to do with the focus.

> >> So what do I do?

> >> Thanks,
> >> Ram.

> for the middle mouse, check out the wx.lib.dragscroller and bind it to
> the appropriate events
> for home and end you'll have to do some calculations in relation to the
> bitmap's size on the canvas

cool-RR wrote:

Hello everyone,

I have a problem:
In my wxPython application I've created a wx.ScrolledPanel, in which
there is a big wx.StaticBitmap that needs to be scrolled.

The scroll bars do appear and I can scroll with them, but I'd also
like to be able to scroll with the mouse wheel and the arrow keys on
the keyboard. It would also be nice if the "Home", "Page Up", and
those other keys would function as expected.

I noticed that the mouse wheel does work when I place a wx.TextCtrl
inside the ScrolledPanel and focus on it. I guess this has something
to do with the focus.

It depends on platform, they have different native behaviors for the wheel events. On Windows the wheel events are only sent to the widget that has the focus. If you are on Windows then I guess that in this case the native textctrl is passing them up to the parent.

On the other platforms the wheel events are sent to whichever widget the mouse pointer is positioned over, (possibly even if that app is not in the foreground.) So for scrolled panels you should be able to get the wheel events if you position the pointer over some part of the scrolled panel that is not covered by a child widget.

···

--
Robin Dunn
Software Craftsman

It depends on platform, they have different native behaviors for the

wheel events. On Windows the wheel events are only sent to the widget

that has the focus. If you are on Windows then I guess that in this

case the native textctrl is passing them up to the parent.

On the other platforms the wheel events are sent to whichever widget the

mouse pointer is positioned over, (possibly even if that app is not in

the foreground.) So for scrolled panels you should be able to get the

wheel events if you position the pointer over some part of the scrolled

panel that is not covered by a child widget.

Robin Dunn

Why doesn’t ScrolledPanel have the focus? Even clicking on it does not set it in focus! I tried calling SetFocus() from the code, and it does work and make the mouse wheel function, but the moment you click on anything the ScrolledPanel loses focus and there is no way to make it focused again through the GUI.

Do I need to subclass ScrolledPanel into something that takes focus more aggressively? Or is there a simpler solution built into wxPython?

Thanks,
Ram.

cool-RR wrote:

    It depends on platform, they have different native behaviors for the
    wheel events. On Windows the wheel events are only sent to the widget
    that has the focus. If you are on Windows then I guess that in this
    case the native textctrl is passing them up to the parent.

    On the other platforms the wheel events are sent to whichever widget the
    mouse pointer is positioned over, (possibly even if that app is not in
    the foreground.) So for scrolled panels you should be able to get the
    wheel events if you position the pointer over some part of the scrolled
    panel that is not covered by a child widget.

    --
    Robin Dunn

Why doesn't ScrolledPanel have the focus? Even clicking on it does not set it in focus! I tried calling SetFocus() from the code, and it does work and make the mouse wheel function, but the moment you click on anything the ScrolledPanel loses focus and there is no way to make it focused again through the GUI.

Because it derives from wx.Panel which has code that when it receives the focus will try to reset the focus to its first child that will take the focus. This is needed to make the tab-traversal work when there are nested panels, panels in things like splitters or notebooks, etc..

Do I need to subclass ScrolledPanel into something that takes focus more aggressively? Or is there a simpler solution built into wxPython?

The best thing to do, if possible, is to not have any child widgets on the scrolled window. For example, instead of having a StaticBitmap widget you can draw the bitmap yourself directly on the scrolled window.

Otherwise, I don't think that all of the focus handling and tab traversal of wx.Panel/wx.ScrolledWindow can be overridden... Perhaps instead you could add scrollability to wx.Window yourself without that focus and navigation functionality.

···

--
Robin Dunn
Software Craftsman