Resizing a wxSizer inside a wxScrolledWindow

Hi.

I have a wxScrolledWindow containing a wxBoxSizer(wxVERTICAL) which contains several dozen complex wxPanels. Following the wxScrolledWindow example in the demo everything looks nice. Now I want to remove some of the Panels. By calling sizer.Remove(self.FindWindowById(ID)) ; sizer.Layout() I get rid of the Items, but the Sizer does not get smaller. sizer.GetMinSize() actually gets smaller, but sizer.GetSize() stays the same. This means the Scrollbars don't adjust and and the end of the ScrolledWindow I get a gray area.

To mee it seems self.SetVirtualSize(sizer.GetMinSize()) followed by self.AdjustScrollbars() should fix that, but it didn't. In fact after doing self.SetVirtualSize(sizer.GetMinSize()) I found self.GetVirtualSize() is the same as before an is not changed to the value of sizer.GetMinSize().
I've tried every possible comdination of changing sizes of the Windows/Sizer I could think of, but nothing worked out.

Any hints how to fix this?

Max

···

--
Max Dornseif - http://md.hudora.de/blog/categories/originalContent/
University of Bonn, Germany - ars longa, vita brevis!

Maximillian Dornseif wrote:

Hi.

I have a wxScrolledWindow containing a wxBoxSizer(wxVERTICAL) which contains several dozen complex wxPanels. Following the wxScrolledWindow example in the demo everything looks nice. Now I want to remove some of the Panels. By calling sizer.Remove(self.FindWindowById(ID)) ; sizer.Layout() I get rid of the Items, but the Sizer does not get smaller. sizer.GetMinSize() actually gets smaller, but sizer.GetSize() stays the same. This means the Scrollbars don't adjust and and the end of the ScrolledWindow I get a gray area.

To mee it seems self.SetVirtualSize(sizer.GetMinSize()) followed by self.AdjustScrollbars() should fix that, but it didn't. In fact after doing self.SetVirtualSize(sizer.GetMinSize()) I found self.GetVirtualSize() is the same as before an is not changed to the value of sizer.GetMinSize().
I've tried every possible comdination of changing sizes of the Windows/Sizer I could think of, but nothing worked out.

Please send a minimal but runnable sample that shows the problem.

···

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

[wxScrolled Window not getting smaller]

Example (also at http://deepblack.lolitacoders.org/~drt/test.py in case my Mailtool ruins the source):

from wxPython.wx import *

ID_KILL = 10011

class NewsItem(wxPanel):
     def __init__(self, parent):
         wxPanel.__init__(self, parent, -1, pos = wxPyDefaultPosition,
                          size=wxPyDefaultSize, style=wxSUNKEN_BORDER)

         self.parent = parent
         sizer = wxBoxSizer( wxVERTICAL )
         sizer.AddWindow(wxButton(self, ID_KILL, "Kill %d" % self.GetId(), wxDefaultPosition, wxDefaultSize, 0\
  ))
         self.SetAutoLayout(true)
         self.SetSizer(sizer)
         sizer.Fit(self)
         sizer.SetSizeHints(self)
         EVT_BUTTON(self, ID_KILL, self.OnKill)

     def OnKill(self, event):
         self.parent.removeItem(self.GetId())
         self.Destroy()

class NewsPanel(wxScrolledWindow):
     def __init__(self, parent):
         wxScrolledWindow.__init__(self, parent, -1,
                                   style = wxTAB_TRAVERSAL|wxSIMPLE_BORDER)
         self.sizer = wxBoxSizer(wxVERTICAL)
         for i in range(20):
             self.sizer.Add(NewsItem(self), 0, wxGROW)
         self.sizer.Add(5, 5)
         self.SetAutoLayout(true)
         self.SetSizer(self.sizer)
         self.EnableScrolling(false, true)
         self.SetScrollRate(0, 20)
         self.sizer.SetVirtualSizeHints(self)
         self.SetSize((660, 400))

     def removeItem(self, cId):
         self.sizer.Remove(self.FindWindowById(cId))
         print self.sizer.GetMinSize(), self.sizer.GetSize(), '-', self.GetSize(), self.GetVirtualSize()
         # tried this:
         # self.sizer.SetVirtualSizeHints(self)
         # and this:
         self.SetVirtualSize(self.sizer.GetMinSize())
         # the last line actually reduces the window's width but not the heigth
         self.Layout()
         self.AdjustScrollbars()
         print self.sizer.GetMinSize(), self.sizer.GetSize(), '-', self.GetSize(), self.GetVirtualSize()

class MainFrame(wxFrame):
     def __init__(self, parent, id, title,
         pos = wxPyDefaultPosition, size = wxPyDefaultSize,
         style = wxDEFAULT_FRAME_STYLE ):
         wxFrame.__init__(self, parent, id, title, pos, size, style)
         self.newspanel = NewsPanel(self)

class TvApp(wxApp):
     def OnInit(self):
         wxInitAllImageHandlers()
         frame = MainFrame(None, -1, "TVL", wxPoint(20,20), wxSize(500,340) )
         frame.Show(true)
         return true

app = TvApp(0)
app.MainLoop()

···

--
Max Dornseif - http://md.hudora.de/blog/categories/originalContent/
University of Bonn, Germany - ars longa, vita brevis!

[...]

don't ask me why, but this works (on GTK at least)... well, almost: there are still some problems if the scrollbar isn't at the top position, but at least the window does get smaller

class NewsPanel(wxScrolledWindow):
      # [...]
      def removeItem(self, cId):
         self.sizer.Remove(self.FindWindowById(cId))
         print self.sizer.GetMinSize(), self.sizer.GetSize(), '-', self.GetSize(), self.GetVirtualSize()
         w, h = self.sizer.GetMinSize()
         self.SetVirtualSizeHints(w, h)
         print self.sizer.GetMinSize(), self.sizer.GetSize(), '-', self.GetSize(), self.GetVirtualSize()

Anyway, I think that also your original code should work, so it seems a bug to me...

Cheers,
Alberto

···

On Fri, 8 Nov 2002 19:51:21 +0100 Maximillian Dornseif <md@hudora.de> wrote:

[wxScrolled Window not getting smaller]

Example (also at http://deepblack.lolitacoders.org/~drt/test.py in case
my Mailtool ruins the source):

From: Alberto Griggio

> Date: Fri, 8 Nov 2002 21:09:00 +0100

>
> > [wxScrolled Window not getting smaller]
> >
> > Example (also at http://deepblack.lolitacoders.org/~drt/test.py in case
> > my Mailtool ruins the source):
>
> don't ask me why, but this works (on GTK at least)... well, almost: there are still
> some problems if the scrollbar isn't at the top position, but at least the window does
> get smaller
>
> class NewsPanel(wxScrolledWindow):
> # [...]
> def removeItem(self, cId):
> self.sizer.Remove(self.FindWindowById(cId))
> print self.sizer.GetMinSize(), self.sizer.GetSize(), '-', self.GetSize(), self.GetVirtualSize()
> w, h = self.sizer.GetMinSize()
> self.SetVirtualSizeHints(w, h)
> print self.sizer.GetMinSize(), self.sizer.GetSize(), '-', self.GetSize(), self.GetVirtualSize()
>
> Anyway, I think that also your original code should work, so it seems a bug to me...

This worked for me (MacOS 10.2 / wxPython 2.3.3.1), too - even without the Problems you mention.

Thanks a lot

Max

···

On Fri, 8 Nov 2002 19:51:21 +0100 > Maximillian Dornseif <md@hudora.de> wrote: