Re[2]: how do I force scrollbars to appear? (wxScro lledWindow/sizer ques tion)

Nigel Moriarty wrote:

I tried to run you code but it has several bugs. I would
suggest you take the code from the demo and implement
each step from there.

@#$^!... There are two extra "-" signs in my previous
post, because linebreaks got inserted by either windows or
Outlook. When I cut these out, the program worked again for
me; I don't *think* there are any other "bugs" in the code...

As for what you suggested, the trouble is that the demo doesn't
deal with creating the extent for the scrollable area at all;
this is handled by the demo framework. I *did* start from the
ScrolledPanel demo source, but then tried to apply it to a
popup dialog, and ran into problems. (If there were a scrolled
dialog window demo, I'd be all set!)

I've included the (modified) program again (so that no line is

80 chars!); hopefully this time it will work for you...

(Also, if anyone could just look at the section in the
constructor for setting the scrollbar up-- marked with ###,
and see if they can tell what I've done wrong, that would be
greatly appreciated...)

Thanks again,
Will Sadkin
Parlance Corporation

···

============================================================
import sys, traceback
from wxPython.wx import *

class TestDialog(wxDialog):
    def __init__(self, parent, id, title, num_machines=4,
        pos = wxPyDefaultPosition, size = wxPyDefaultSize,
        style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ):

        wxDialog.__init__(self, parent, id, title, pos, size, style)
        self.sw = wxScrolledWindow(self, -1, style = wxTAB_TRAVERSAL)
        grid = wxFlexGridSizer( 0, 3, 0, 0 )
        
        # draw the header widgets
        col1hdr = wxStaticText( self.sw, -1, "Machine")
        col1hdr.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
        col2hdr = wxStaticText( self.sw, -1, "Line")
        col2hdr.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
        col3hdr = wxStaticText( self.sw, -1, "Line Group" )
        col3hdr.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
        
        grid.AddWindow( col1hdr, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 35 )
        grid.AddWindow( col2hdr, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 25 )
        grid.AddWindow( col3hdr, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 25 )

        combovalues = ['group1', 'group2', 'group3']
        data =
        for i in range(num_machines):
            for j in range(1,5):
                data.append(('machine%d' % (i+1), j, 'group1'))

        currentmachine = ''
        self.combos =
        for machine, line, value in data:
            if machine != currentmachine:
                currentmachine = machine
                grid.AddSpacer( 20, 15, 0, wxALIGN_CENTRE|wxALL, 5 )
                grid.AddSpacer( 20, 15, 0, wxALIGN_CENTRE|wxALL, 5 )
                grid.AddSpacer( 20, 15, 0, wxALIGN_CENTRE|wxALL, 5 )
                machinename = wxStaticText( self.sw, -1, currentmachine )
                grid.AddWindow( machinename, 0, wxALIGN_CENTRE|wxALL, 5 )

            else:
                grid.AddSpacer(20, 10, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 5 )

            linelabel = wxStaticText( self.sw, -1, str(line))
            combo = wxComboBox( self.sw, NewId(), "",
                                wxDefaultPosition,
                                wxSize(140,-1),
                                combovalues, wxCB_DROPDOWN )

            grid.AddWindow( linelabel, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 5 )
            grid.AddWindow( combo, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 5 )
            combo.SetStringSelection( value )
        
### I'm sure this block has to be different, but I don't know how...
        self.sw.SetSizer(grid)
        self.sw.EnableScrolling(false, true)
        self.sw.SetScrollRate(0, 20)
        self.sw.SetAutoLayout( true )
        
        grid.Fit( self.sw )
        grid.SetSizeHints( self.sw )
        grid.SetVirtualSizeHints(self.sw)
        
        w, h = self.GetSizeTuple()
        print "dialog size:", w, h
        size = self.sw.GetSizer().GetMinSize()
        print "scrolled window sizer min size:", size.x, size.y

        self.sw.SetScrollbars(1, 1, size.x, size.y, 0, 0, true)
###
        
    def OnSize(self, event):
        size = event.GetSize()
        print "size", size.x, size.y
        event.Skip()
        
#----------------------------------------------------------

if __name__ == '__main__':

    class TestApp(wxApp):
        def OnInit(self):
            try:
                wxInitAllImageHandlers()
                self.frame = wxFrame(NULL, -1, "Test",
                                     wxPoint(220,220),
                                     wxSize(60,60) )
                button = wxButton( self.frame, NewId(), "Push Me")
                EVT_BUTTON(self, button.GetId(), self.OnTest)
                
            except:
                traceback.print_exc()
                return false
            
            return true
            
        def Show(self):
            self.frame.Show(true)

        def OnTest(self, evt):
            dlg = TestDialog( self.frame, -1, 'Test Dialog',
                              size=wxSize(400,400))
            dlg.Centre()
            dlg.ShowModal()
#----------------------------------------------------------
   
    try:
        app = TestApp(0)
        app.Show()
        app.MainLoop()
    except:
        traceback.print_exc()

Hi Will. That last post wasn't too helpful. There are no *bugs* - the 80 char thing was easy to fix, but the other issue Nigel may have had (as well as myself) is I am running an older wxPython which doesn't support a couple of the methods you have used. No problem - comment them out!

Anyway, I do not have a solution for you yet, but I haven't looked at it that long. Since the OnSize refreshes it, you could always post a size event and hack it that way for now. However, it has something to do with the way things are added to the dialog in my opinion. I'll have another look tomorrow...

Incidentally - if you want to see something funny, change the SetScrollbars to this:

self.sw.SetScrollbars(1, 1, size.x + 1, size.y + 1)

You get a scrollbar right away like you wanted, but it is 3/4 of the way across the screen. It then refreshes when you resize....hehe. GUI programming is fun!

Mark.

Will Sadkin wrote:

···

Nigel Moriarty wrote:

I tried to run you code but it has several bugs. I would suggest you take the code from the demo and implement each step from there.
   
@#$^!... There are two extra "-" signs in my previous
post, because linebreaks got inserted by either windows or
Outlook. When I cut these out, the program worked again for me; I don't *think* there are any other "bugs" in the code...

As for what you suggested, the trouble is that the demo doesn't
deal with creating the extent for the scrollable area at all;
this is handled by the demo framework. I *did* start from the
ScrolledPanel demo source, but then tried to apply it to a
popup dialog, and ran into problems. (If there were a scrolled
dialog window demo, I'd be all set!)

I've included the (modified) program again (so that no line is

80 chars!); hopefully this time it will work for you...
   

(Also, if anyone could just look at the section in the constructor for setting the scrollbar up-- marked with ###, and see if they can tell what I've done wrong, that would be greatly appreciated...)

Thanks again,
Will Sadkin
Parlance Corporation

import sys, traceback
from wxPython.wx import *

class TestDialog(wxDialog):
   def __init__(self, parent, id, title, num_machines=4,
       pos = wxPyDefaultPosition, size = wxPyDefaultSize,
       style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ):

       wxDialog.__init__(self, parent, id, title, pos, size, style)
       self.sw = wxScrolledWindow(self, -1, style = wxTAB_TRAVERSAL)
       grid = wxFlexGridSizer( 0, 3, 0, 0 )
              # draw the header widgets
       col1hdr = wxStaticText( self.sw, -1, "Machine")
       col1hdr.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
       col2hdr = wxStaticText( self.sw, -1, "Line")
       col2hdr.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
       col3hdr = wxStaticText( self.sw, -1, "Line Group" )
       col3hdr.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
              grid.AddWindow( col1hdr, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 35 )
       grid.AddWindow( col2hdr, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 25 )
       grid.AddWindow( col3hdr, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 25 )

       combovalues = ['group1', 'group2', 'group3']
       data =
       for i in range(num_machines):
           for j in range(1,5):
               data.append(('machine%d' % (i+1), j, 'group1'))

       currentmachine = ''
       self.combos =
       for machine, line, value in data:
           if machine != currentmachine:
               currentmachine = machine
               grid.AddSpacer( 20, 15, 0, wxALIGN_CENTRE|wxALL, 5 )
               machinename = wxStaticText( self.sw, -1, currentmachine )
               grid.AddWindow( machinename, 0, wxALIGN_CENTRE|wxALL, 5 )

           else:
               grid.AddSpacer(20, 10, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 5 )

           linelabel = wxStaticText( self.sw, -1, str(line))
           combo = wxComboBox( self.sw, NewId(), "",
                               wxDefaultPosition,
                               wxSize(140,-1), combovalues, wxCB_DROPDOWN )

           grid.AddWindow( linelabel, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 5 )
           grid.AddWindow( combo, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 5 )
           combo.SetStringSelection( value )
       ### I'm sure this block has to be different, but I don't know how...
       self.sw.SetSizer(grid)
       self.sw.EnableScrolling(false, true)
       self.sw.SetScrollRate(0, 20)
       self.sw.SetAutoLayout( true )
              grid.Fit( self.sw )
       grid.SetSizeHints( self.sw )
       grid.SetVirtualSizeHints(self.sw)
              w, h = self.GetSizeTuple()
       print "dialog size:", w, h
       size = self.sw.GetSizer().GetMinSize()
       print "scrolled window sizer min size:", size.x, size.y

       self.sw.SetScrollbars(1, 1, size.x, size.y, 0, 0, true)
###
          def OnSize(self, event):
       size = event.GetSize()
       print "size", size.x, size.y
       event.Skip()
       #----------------------------------------------------------

if __name__ == '__main__':

   class TestApp(wxApp): def OnInit(self):
           try:
               wxInitAllImageHandlers()
               self.frame = wxFrame(NULL, -1, "Test",
                                    wxPoint(220,220),
                                    wxSize(60,60) )
               button = wxButton( self.frame, NewId(), "Push Me")
               EVT_BUTTON(self, button.GetId(), self.OnTest)
                          except:
               traceback.print_exc()
               return false
                      return true
                  def Show(self):
           self.frame.Show(true)

       def OnTest(self, evt):
           dlg = TestDialog( self.frame, -1, 'Test Dialog',
                             size=wxSize(400,400))
           dlg.Centre()
           dlg.ShowModal()
#----------------------------------------------------------
     try:
       app = TestApp(0)
       app.Show()
       app.MainLoop()
   except:
       traceback.print_exc()

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

Mark was correct to say that the old version of python doesn't work with
your code.

One thing I noticed was that the scrolledwindow is not in a sizer
(wxBoxSizer of one slot would be ok). This
may well be your problem.

Nigel

···

On Wed, 11 Dec 2002 17:53:21 -0500 Will Sadkin <wsadkin@nameconnector.com> wrote:

Nigel Moriarty wrote:
> I tried to run you code but it has several bugs. I would
> suggest you take the code from the demo and implement
> each step from there.

@#$^!... There are two extra "-" signs in my previous
post, because linebreaks got inserted by either windows or
Outlook. When I cut these out, the program worked again for
me; I don't *think* there are any other "bugs" in the code...

As for what you suggested, the trouble is that the demo doesn't
deal with creating the extent for the scrollable area at all;
this is handled by the demo framework. I *did* start from the
ScrolledPanel demo source, but then tried to apply it to a
popup dialog, and ran into problems. (If there were a scrolled
dialog window demo, I'd be all set!)

I've included the (modified) program again (so that no line is
> 80 chars!); hopefully this time it will work for you...
(Also, if anyone could just look at the section in the
constructor for setting the scrollbar up-- marked with ###,
and see if they can tell what I've done wrong, that would be
greatly appreciated...)

Thanks again,
Will Sadkin
Parlance Corporation

import sys, traceback
from wxPython.wx import *

class TestDialog(wxDialog):
    def __init__(self, parent, id, title, num_machines=4,
        pos = wxPyDefaultPosition, size = wxPyDefaultSize,
        style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ):

        wxDialog.__init__(self, parent, id, title, pos, size, style)
        self.sw = wxScrolledWindow(self, -1, style = wxTAB_TRAVERSAL)
        grid = wxFlexGridSizer( 0, 3, 0, 0 )
        
        # draw the header widgets
        col1hdr = wxStaticText( self.sw, -1, "Machine")
        col1hdr.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
        col2hdr = wxStaticText( self.sw, -1, "Line")
        col2hdr.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
        col3hdr = wxStaticText( self.sw, -1, "Line Group" )
        col3hdr.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
        
        grid.AddWindow( col1hdr, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 35 )
        grid.AddWindow( col2hdr, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 25 )
        grid.AddWindow( col3hdr, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 25 )

        combovalues = ['group1', 'group2', 'group3']
        data =
        for i in range(num_machines):
            for j in range(1,5):
                data.append(('machine%d' % (i+1), j, 'group1'))

        currentmachine = ''
        self.combos =
        for machine, line, value in data:
            if machine != currentmachine:
                currentmachine = machine
                grid.AddSpacer( 20, 15, 0, wxALIGN_CENTRE|wxALL, 5 )
                grid.AddSpacer( 20, 15, 0, wxALIGN_CENTRE|wxALL, 5 )
                grid.AddSpacer( 20, 15, 0, wxALIGN_CENTRE|wxALL, 5 )
                machinename = wxStaticText( self.sw, -1, currentmachine )
                grid.AddWindow( machinename, 0, wxALIGN_CENTRE|wxALL, 5 )

            else:
                grid.AddSpacer(20, 10, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT,
5 )

            linelabel = wxStaticText( self.sw, -1, str(line))
            combo = wxComboBox( self.sw, NewId(), "",
                                wxDefaultPosition,
                                wxSize(140,-1),
                                combovalues, wxCB_DROPDOWN )

            grid.AddWindow( linelabel, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT,
5 )
            grid.AddWindow( combo, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 5 )
            combo.SetStringSelection( value )
        
### I'm sure this block has to be different, but I don't know how...
        self.sw.SetSizer(grid)
        self.sw.EnableScrolling(false, true)
        self.sw.SetScrollRate(0, 20)
        self.sw.SetAutoLayout( true )
        
        grid.Fit( self.sw )
        grid.SetSizeHints( self.sw )
        grid.SetVirtualSizeHints(self.sw)
        
        w, h = self.GetSizeTuple()
        print "dialog size:", w, h
        size = self.sw.GetSizer().GetMinSize()
        print "scrolled window sizer min size:", size.x, size.y

        self.sw.SetScrollbars(1, 1, size.x, size.y, 0, 0, true)
###
        
    def OnSize(self, event):
        size = event.GetSize()
        print "size", size.x, size.y
        event.Skip()
        
#----------------------------------------------------------

if __name__ == '__main__':

    class TestApp(wxApp):
        def OnInit(self):
            try:
                wxInitAllImageHandlers()
                self.frame = wxFrame(NULL, -1, "Test",
                                     wxPoint(220,220),
                                     wxSize(60,60) )
                button = wxButton( self.frame, NewId(), "Push Me")
                EVT_BUTTON(self, button.GetId(), self.OnTest)
                
            except:
                traceback.print_exc()
                return false
            
            return true
            
        def Show(self):
            self.frame.Show(true)

        def OnTest(self, evt):
            dlg = TestDialog( self.frame, -1, 'Test Dialog',
                              size=wxSize(400,400))
            dlg.Centre()
            dlg.ShowModal()
#----------------------------------------------------------
   
    try:
        app = TestApp(0)
        app.Show()
        app.MainLoop()
    except:
        traceback.print_exc()

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

--
Nigel W. Moriarty
Building 4R0230
Physical Biosciences Division
Lawrence Berkeley National Laboratory
Berkeley, CA 94720-8235
Phone : 510-486-5709
Fax : 510-486-5909
Email : NWMoriarty@LBL.gov
Web : CCI.LBL.gov

I tried your code, and got an error in the init method. It's flagged below, and might be a hint...

Will Sadkin wrote:

import sys, traceback
from wxPython.wx import *

class TestDialog(wxDialog):
    def __init__(self, parent, id, title, num_machines=4,
        pos = wxPyDefaultPosition, size = wxPyDefaultSize,
        style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ):

        wxDialog.__init__(self, parent, id, title, pos, size, style)
        self.sw = wxScrolledWindow(self, -1, style = wxTAB_TRAVERSAL)
        grid = wxFlexGridSizer( 0, 3, 0, 0 )
                # draw the header widgets
        col1hdr = wxStaticText( self.sw, -1, "Machine")
        col1hdr.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
        col2hdr = wxStaticText( self.sw, -1, "Line")
        col2hdr.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
        col3hdr = wxStaticText( self.sw, -1, "Line Group" )
        col3hdr.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
                grid.AddWindow( col1hdr, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 35 )
        grid.AddWindow( col2hdr, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 25 )
        grid.AddWindow( col3hdr, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 25 )

        combovalues = ['group1', 'group2', 'group3']
        data =
        for i in range(num_machines):
            for j in range(1,5):
                data.append(('machine%d' % (i+1), j, 'group1'))

        currentmachine = ''
        self.combos =
        for machine, line, value in data:
            if machine != currentmachine:
                currentmachine = machine
                grid.AddSpacer( 20, 15, 0, wxALIGN_CENTRE|wxALL, 5 )
                machinename = wxStaticText( self.sw, -1, currentmachine )
                grid.AddWindow( machinename, 0, wxALIGN_CENTRE|wxALL, 5 )

            else:
                grid.AddSpacer(20, 10, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 5 )

            linelabel = wxStaticText( self.sw, -1, str(line))
            combo = wxComboBox( self.sw, NewId(), "",
                                wxDefaultPosition,
                                wxSize(140,-1), combovalues, wxCB_DROPDOWN )

            grid.AddWindow( linelabel, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 5 )
            grid.AddWindow( combo, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 5 )
            combo.SetStringSelection( value )

Right here, I get the following warning:
Traceback (most recent call last):
   File "<stdin>", line 103, in OnTest
   File "<stdin>", line 53, in __init__
AttributeError: wxComboBox instance has no attribute 'SetStringSelection'

···

        ### I'm sure this block has to be different, but I don't know how...
        self.sw.SetSizer(grid)
        self.sw.EnableScrolling(false, true)
        self.sw.SetScrollRate(0, 20)
        self.sw.SetAutoLayout( true )
                grid.Fit( self.sw )
        grid.SetSizeHints( self.sw )
        grid.SetVirtualSizeHints(self.sw)
                w, h = self.GetSizeTuple()
        print "dialog size:", w, h
        size = self.sw.GetSizer().GetMinSize()
        print "scrolled window sizer min size:", size.x, size.y

        self.sw.SetScrollbars(1, 1, size.x, size.y, 0, 0, true)
###
            def OnSize(self, event):
        size = event.GetSize()
        print "size", size.x, size.y
        event.Skip()
        #----------------------------------------------------------

if __name__ == '__main__':

    class TestApp(wxApp): def OnInit(self):
            try:
                wxInitAllImageHandlers()
                self.frame = wxFrame(NULL, -1, "Test",
                                     wxPoint(220,220),
                                     wxSize(60,60) )
                button = wxButton( self.frame, NewId(), "Push Me")
                EVT_BUTTON(self, button.GetId(), self.OnTest)
                            except:
                traceback.print_exc()
                return false
                        return true
                    def Show(self):
            self.frame.Show(true)

        def OnTest(self, evt):
            dlg = TestDialog( self.frame, -1, 'Test Dialog',
                              size=wxSize(400,400))
            dlg.Centre()
            dlg.ShowModal()
#----------------------------------------------------------
       try:
        app = TestApp(0)
        app.Show()
        app.MainLoop()
    except:
        traceback.print_exc()