Hi there,
(I’ll start off by saying I’m using the GTK version on Ubuntu)
I’m trying to create an area in my app that has custom scroll behavior. Basically a panel of objects that scroll horizontally. I do not want to the scroll bars to be visible and so I am calling Scroll(x,y) on mouse wheel events, so that you can scroll over any part of the panel.
Everything works fine until I add the following line to hide the bars:
self.scrollable.ShowScrollbars(horz=wx.SHOW_SB_NEVER, vert=wx.SHOW_SB_NEVER)
(Which is the only way that I’m aware of to hide the scroll bar. Is there another?).
The bar does disappear, but the panel itself changes it’s rendering behavior. Children don’t render as if they are part of a scrolling window, they get squished. And if you do call Scroll(…) at that point, the children that should be off screen to the right are not rendered at all (or don’t exist).
Bellow, I have included a short program to show what I am talking about. Here are two screenshots:
Without hiding the bars (top photo): (Buttons continue rendering off screen, and can be scrolled to. The scroll bar is not visible but will show when you hover over it)
With hidden bars (bottom photo): (There should be several more buttons to the right)
Thank you.
To me this behavior seems like it’s probably unintended. It’s the same story with both ScrolledWindow and ScrolledPanel.
Has anyone experienced this before/know a work around?
Sample:
Here is the sample program. Comment/Uncomment line 33 to observe the changes.
(Also recommend setting the frame width to something that cuts off one of the buttons so that you can observe that change)
import wx
# Run this and click the scroll button
# Then comment out the noted line (33) and re run. Notice how it changes.
class AppWindow(wx.Frame):
def __init__(self, parent, title):
self.dirname=''
# Pick a window width that causes one of the buttons to be compressed
wx.Frame.__init__(self, parent, title=title, size=(350,200))
frame_sizer = wx.BoxSizer(wx.VERTICAL)
# Create a scrollable panel
self.scrollable = wx.ScrolledWindow(self)
scrollable_sizer = wx.BoxSizer(wx.HORIZONTAL)
# Add Buttons
for i in range(1, 8):
scrollable_sizer.Add(wx.Button(self.scrollable, label=f"Button {i}"), 1, wx.ALL, 5)
# Add a scrollbar
self.scrollable.SetScrollbars(10,10,10,10)
self.scrollable.SetSizer(scrollable_sizer)
frame_sizer.Add(self.scrollable, 1, wx.ALL | wx.EXPAND)
scroll_right = wx.Button(self, label="Click to Scroll Right")
scroll_right.Bind(wx.EVT_BUTTON, self.Scroll)
frame_sizer.Add(scroll_right, 0, wx.ALL, 5)
# COMMENT OUT THIS LINE #
# This is the line in question. Comment it out and see the difference.
self.scrollable.ShowScrollbars(horz=wx.SHOW_SB_NEVER, vert=wx.SHOW_SB_NEVER)
# ^^^^^^ THIS ONE ^^^^^^^ #
# All it should do is hide the scroll bars but it also changes how the content is rendered
self.SetSizer(frame_sizer)
self.Show()
# Scrolls to right
def Scroll(self, event):
print("Scroll")
start, _ = self.scrollable.GetViewStart()
self.scrollable.Scroll(3+start,0)
app = wx.App(False)
frame = AppWindow(None, "Test")
app.MainLoop()