How do I create a frame with a scrollbar

In wxPython, scrollbars are not an element of the frame itself, but rather are controlled by the class wx.ScrolledWindow. You can use a wx.ScrolledWindow any place that you would use a wx.Panel, and the scrollbars move all the items that are inside that scrolled window. Figure 8.5 and figure 8.6 display a scroller in action, both in its initial state and after it has been scrolled. The top-left button scrolls off the viewport, and the lower-right button scrolls on.

In this section, we'll discuss how to create a window with a scrollbar and how to manipulate the scrolling behavior from within your program.

□ Scrollbar Example

I Scroll Me j

Figure 8.5 A wx.Scrolled-Wi after initial creation

How to create the scrollbar

Listing 8.7 displays the code used to create the scrolled window.

Listing 8.7 Creating a simple scrolled window import wx class ScrollbarFrame(wx.Frame):

wx.Frame._init_(self, None, -1, 'Scrollbar Example', size=(3 00, 200))

Wxpython Scrollbar

Figure 8.6 The same window after it has been scrolled

Lndow

Figure 8.6 The same window after it has been scrolled self.scroll = wx.ScrolledWindow(self, -1) self.scroll.SetScrollbars(1, 1, 600, 400) self.button = wx.Button(self.scroll, -1, "Scroll Me", pos=(50, 20))

self.Bind(wx.EVT_BUTTON, self.OnClickTop, self.button) self.button2 = wx.Button(self.scroll, -1, "Scroll Back", pos=(500, 350)) self.Bind(wx.EVT_BUTTON, self.OnClickBottom, self.button2)

def OnClickTop(self, event):

self.scroll.Scroll(6 00, 400)

def OnClickBottom(self, event): self.scroll.Scroll(1, 1)

app = wx.PySimpleApp() frame = ScrollbarFrame() frame.Show() app.MainLoop()

The constructor for wx.ScrolledWindow is nearly identical to the one for wx.Panel:

wx.ScrolledWindow(parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.HSCROLL | wx.VSCROLL, name="scrolledWindow")

All of the attributes behave as you might expect, although the size attribute is the physical size of the panel within its parent, and not the logical size of the window for scrolling.

Specifying scroll area size

There are several automatic methods of specifying the size of the scrolling area. The most manual way, as displayed in listing 8.1, uses the method SetScrollBars:

SetScrollbars(pixelsPerUnitX, pixelsPerUnitY, noUnitsX, noUnitsY, xPos=0, yPos=0, noRefresh=False)

The key concept is that of scroll unit, which is the amount of space the window shifts for one movement of the scrollbar (often called a thumb shift, as opposed to a page shift). The first two parameters, pixelsPerUnitX and PixelsPerUnitY allow you to set the size of a scroll unit in both dimensions. The second two parameters, noUnitsX, and noUnitsY allow you to set the size of the scroll area in terms of scroll units. In other words, the size of the scroll area in pixels is (pixels-PerUnitX * noUnitsX, pixelsPerUnitY * noUnitsY). Listing 8.7 avoids any potential confusion by making the scroll unit one pixel. The xPos and yPos parameters allow you set the initial position of the scrollbars in terms of scroll units (not pixels), and the noRefresh argument, if true, prevents automatic refresh of the window after any scroll caused by the SetScrollbars() call.

There are three other methods that you can use to set the size of the scrolling area and then separately set the scroll rate. You might find these methods easier to use, because they allow you to specify dimensions more directly. You can use the scroll window method SetVirtualSize(), by setting the size directly in pixels, as in the following.

self.scroll.SetVirtualSize((600, 4 00))

Using the method Fitlnside(), you can set up the widgets inside the scroll area so that the scroll window bounds them. This method sets the boundaries of the scroll window to the minimum required to exactly fit all sub-windows:

self.scroll.FitInside()

A common use case for Fitlnside() is when there is exactly one widget inside the scroll window (like a text area), and the logical size of that widget has already been set. If we had used Fitlnside() in listing 8.7, a smaller scroll area would have been created, since the area would exactly match the edge of the lower-right button, rather than having additional padding.

Finally, if the scroll window has a sizer set inside it, using SetSizer() sets the scrolling area to the size of the widgets as managed by the sizer. This is the mechanism used most frequently in a complex layout. For more detailed information about sizers, see chapter 11.

With all three of these mechanisms, the scroll rate needs to be set separately using the method SetScrollRate(), as in the following.

self.scroll.SetScrollRate(1, 1)

The arguments are the scroll unit size in the x and y directions, respectively. A size greater than zero enables scrolling in that direction.

Scrollbar events

The button event handlers in listing 8.7 programmatically change the position of the scrollbars using the Scroll() method. This method takes the x and y coordinates of the scroll window, using scroll units and not pixels.

In chapter 7, we promised a listing of the events you can capture from a scrollbar, since they are also used to control sliders. Table 8.7 lists all scroll events handled internally by the scroller window. Typically, you won't use many of these events unless you are building custom widgets.

Table 8.7 Events of a scroll bar

Event Type

Description

EVT_SCROLL

Called when any scroll event is triggered.

EVT_SCROLL_BOTTOM

Triggered when the user moves the scrollbar to the maximum end of its range (the bottom or right side, depending on orientation).

EVT_SCROLL_ENDSCROLL

On MS Windows, triggered at the end of any scrolling session, whether it be caused by mouse drag or key press.

EVT_SCROLL_LINEDOWN

Triggered when the user moves the scrollbar down one line.

EVT_SCROLL_LINEUP

Triggered when the user moves the scrollbar up one line.

EVT_SCROLL_PAGEDOWN

The user has moved the scrollbar down one page.

EVT_SCROLL_PAGEUP

The scrollbar has moved up one page.

EVT_SCROLL_THUMBRELEASE

Called at the end of any scroll session that has been driven by the user actually dragging the scrollbar thumb with the mouse.

EVT_SCROLL_THUMBTRACK

Called repeatedly while the thumb is being dragged.

EVT_SCROLL_TOP

Triggered when the user moves the scrollbar to the minimum end of its range, which is either the top or left, depending on orientation.

The exact definition of line and page depends on the scroll units you've set, one line is one scroll unit and one page is the number of complete scroll units that fit in the visible portion of the scrolled window. For each of the evt_scroll* events listed in the table there is a corresponding evt_scrollwin* event emitted by the wx.ScrolledWindow in response to the events from its scroll bars.

There is a wxPython-specific scrolled window subclass, wx.lib.scrolledpanel. ScrolledPanel, that allows you to automatically set up scrolling on panels that are using a sizer to manage the layout of child widgets. An added benefit of the wx.lib.scrolledpanel.ScrolledPanel is it allows the user to select the tab key to move between subwidgets. The panel automatically scrolls to put the newly focused widget in view. To use wx.lib.scrolledpanel.ScrolledPanel, declare it like a scrolled window, then, after all the sub-windows have been added, call the following method.

SetupScrolling(self, scroll_x=True, scroll_y=True, rate_x=20, rate_y=2 0)

The rate_x and rate_y are the scroll units of the window, and the class automatically sets the virtual size based on the size of the subwidgets as calculated by the sizer.

Remember, when determining the position of a widget inside a scrolled window, its position is always the physical position of the widget relative to the actual origin of the scroll window in the display frame, not the widget's logical position relative to the virtual size of the frame. This is true even if the widget is no longer visible. For example, after clicking on the Scroll Me button in figure 8.5, the button reports its position as (-277, -237). If this isn't what you want, switch between the display coordinates and the logical coordinates using the methods Calc-ScrolledPosition(x, y) and CalcUnscrolledPosition(x, y). In each case, after the button click moves the scroller to the bottom right, you pass the coordinates of the point, and the scroll window returns an (x, y) tuple, as in the following.

CalcUnscrolledPostion(-277, -237) returns (50, 20)

Was this article helpful?

0 -3

Responses

  • Klaudia
    How create self scroll bars?
    9 years ago
  • FABIANA
    How to bind scroll event of a panel and trigger it whenever scrollbar is moved?
    8 years ago
  • monica
    How to create a scroll bar python?
    5 years ago
  • tony sasi
    How to maintain the scrollbar that is automatically created by extending the table in python?
    4 years ago
  • MEWAEL
    How to create frames in Wxpython'?
    11 months ago
  • Esa
    How to loack all scrollbars in pyqt5 in python?
    10 months ago
  • Finn
    How to create a frame wxpython?
    8 months ago
  • Steffen
    How to create scrollbar python?
    6 months ago
  • Leon
    How to set scroll bars wxpython?
    6 months ago

Post a comment