Scrollbar Help

Hello all,
  I have been banging my head against the wall for days now trying to
figure out the why I can't get scrollbars to work. I have enclosed a
little program which shows what my problem is. It seems that if I add
objects to a BoxSizer, then set the sizer of MyWindow, I don't get the
scrollbar. But, if I don't use the BoxSizer for MyWindow, the
scrollbars appear.

  If you run the enclosed pgm with no args, you get scrollbars. This is
is because you don't use the BoxSizer for MyWindow.
  # ./broken.py

  Running the pgm as follows will make the buttons imperceptible(I still
don't know why this is happening):
  # ./broken.py -usebroken

  Running the pgm as follows will make the buttons visible, but you
can't see the scrollbar:
  # ./broken.py -usebroken -noscroll

  I am sure it's something I am doing, I just don't know what.

Thanks,
Chuck

#!/usr/bin/env python

···

#
#

import sys
from wxPython.wx import *
DFL_WID = -1

use_broken = False
show_noscroll = False

class MyScroller( wxScrolledWindow ):
  def __init__( self, parent, id ):
    wxScrolledWindow.__init__( self, parent, id, style=wxVSCROLL )
    self.SetScrollRate( 5, 5 )
    mainLayout = wxBoxSizer( wxVERTICAL )

    for i in range( 0, 100 ):
      mainLayout.Add( wxButton( self, DFL_WID, 'Button' + str(i)) )

    if show_noscroll:
      self.SetAutoLayout( True )
      self.SetSizerAndFit( mainLayout )
    else:
      self.SetSizer( mainLayout )

class MyWindow( wxFrame ):
  def __init__( self, parent, id, title='MyWindow' ):
    wxFrame.__init__( self, parent, id, title )

    if use_broken:
      frameLayout = wxBoxSizer( wxVERTICAL )
      frameLayout.Add( MyScroller( self, DFL_WID ) )
      self.SetSizer( frameLayout )
    else:
      scroll = MyScroller( self, DFL_WID )

    self.Show( True )

if len( sys.argv ) >= 2:
  for a in sys.argv:
    if a == '-usebroken':
      use_broken = True
    elif a == '-noscroll':
      show_noscroll = True
    else:
      continue

app = wxPySimpleApp()
frame = MyWindow( None, DFL_WID )
app.MainLoop()

Oh yeah, I'm using wxPython-2.4.2.4 (gentoo)

Chuck

Chuck Winters wrote:

Hello all,
  I have been banging my head against the wall for days now trying to
figure out the why I can't get scrollbars to work. I have enclosed a
little program which shows what my problem is. It seems that if I add
objects to a BoxSizer, then set the sizer of MyWindow, I don't get the
scrollbar. But, if I don't use the BoxSizer for MyWindow, the
scrollbars appear.

  If you run the enclosed pgm with no args, you get scrollbars. This is
is because you don't use the BoxSizer for MyWindow.
  # ./broken.py

Since the frame's default behavior is to size single child windows to fill the client size and the virtual size of the scrolled window is larger than this then the scrollbars are shown.

In your other cases the ScrolledWindow is being resized to be large enough to show all of its contents so it doesn't get scrollbars. But since it is larger than the frame then it is clipped.

BTW, you should look at wx.lib.scrolledpanel

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Thanks for the reply. Comments inline.

Chuck Winters wrote:
> Hello all,
> I have been banging my head against the wall for days now trying to
> figure out the why I can't get scrollbars to work. I have enclosed a
> little program which shows what my problem is. It seems that if I add
> objects to a BoxSizer, then set the sizer of MyWindow, I don't get the
> scrollbar. But, if I don't use the BoxSizer for MyWindow, the
> scrollbars appear.
>
> If you run the enclosed pgm with no args, you get scrollbars. This is
> is because you don't use the BoxSizer for MyWindow.
> # ./broken.py

Since the frame's default behavior is to size single child windows to
fill the client size and the virtual size of the scrolled window is
larger than this then the scrollbars are shown.

Understood, but why the difference when I use a sizer? The frame still
only has one child.

In your other cases the ScrolledWindow is being resized to be large
enough to show all of its contents so it doesn't get scrollbars. But
since it is larger than the frame then it is clipped.

I can see that maybe when I used the SetSizerAndFit that it set the size
of the ScrolledWindow to be the same size as the window. That would
account for the clipping. What about if you run it with only the
-usebroken flag. Then the size of the ScrolledWindow is -1,-1. Why is
it not autosized?
I tried forcing the size, and it worked fine. I then tried adding a
button before the ScrolledWindow, like so:
  ...
  frameLayout.Add( wxButton( self, DFL_WID, 'New Button' ), 0 )
  frameLayout.Add( MyScroller( self, DFL_WID ), 0 )
  ...
To my surprise, MyScroller overwrite the button on the screen. Any
ideas?

BTW, you should look at wx.lib.scrolledpanel

Thanks for the heads-up.

Thanks,
Chuck

···

On Thu, 2005-04-07 at 16:14 -0700, Robin Dunn wrote:

Chuck Winters wrote:

Thanks for the reply. Comments inline.

Chuck Winters wrote:

Hello all,
I have been banging my head against the wall for days now trying to
figure out the why I can't get scrollbars to work. I have enclosed a
little program which shows what my problem is. It seems that if I add
objects to a BoxSizer, then set the sizer of MyWindow, I don't get the
scrollbar. But, if I don't use the BoxSizer for MyWindow, the
scrollbars appear.

If you run the enclosed pgm with no args, you get scrollbars. This is
is because you don't use the BoxSizer for MyWindow.
# ./broken.py

Since the frame's default behavior is to size single child windows to fill the client size and the virtual size of the scrolled window is larger than this then the scrollbars are shown.

Understood, but why the difference when I use a sizer? The frame still
only has one child.

The default single-child behavior only happens when there is no sizer or layout constraints.

In your other cases the ScrolledWindow is being resized to be large enough to show all of its contents so it doesn't get scrollbars. But since it is larger than the frame then it is clipped.

I can see that maybe when I used the SetSizerAndFit that it set the size
of the ScrolledWindow to be the same size as the window. That would
account for the clipping. What about if you run it with only the
-usebroken flag. Then the size of the ScrolledWindow is -1,-1. Why is
it not autosized?

That was probably a 2.4 bug. I didn't see it with 2.5.

I tried forcing the size, and it worked fine. I then tried adding a
button before the ScrolledWindow, like so:
  ...
  frameLayout.Add( wxButton( self, DFL_WID, 'New Button' ), 0 )
  frameLayout.Add( MyScroller( self, DFL_WID ), 0 )
  ...
To my surprise, MyScroller overwrite the button on the screen. Any
ideas?

This also doesn't happen with 2.5.

···

On Thu, 2005-04-07 at 16:14 -0700, Robin Dunn wrote:

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!