Hi,
I ran into a relayout problem on wxGTK. The problem is described
in the docstrings of the attached test program.
Using Python 2.2.3 and wxPython 2.4.0.7 on Windows 2000 works.
The wxGTK problem happens on a Debian based system using
Python 2.2.2 and wxPython 2.4.0.8.
Fortunately for this particular case, I can work around this oddity by
using a GridSizer instead of a BoxSizer.
Still I would really appreciate if somebody could explain what is
going on because relayout is my primary 'waste a day' discipline.
Thanks in advance,
Michael
···
--------------------------------------------------------------------
#!/bin/env python
from wxPython.wx import *
MAX_TEXTS = 3
class TextHeadings(wxPanel):
"""This class displays some texts headers.
Each text header gets an equal amount of the total available width of this panel.
If the number of text headers decreases from three to one the width of the text headers
is correctly adjusted.
When the number of text headers increases while using a wxBoxSizer on wxGTK, the first text
header is still displayed using the full with of the panel.
Using a wxGridSizer or wxMSW instead of wxGTK works as expected.
"""
def __init__(self, parent, id=-1, pos=wxDefaultPosition, size=wxDefaultSize):
wxPanel.__init__(self, parent, id, pos, size)
sizer, self.gps = self._initHeaders(parent)
self.layoutHeaders(3)
def layoutHeaders(self, num):
# Using a wxBoxSizer works on wxMSW, but not on wxGTK
sizer = wxBoxSizer(wxHORIZONTAL)
# Using wxGridSizer works on wxMSW and wxGTK
# sizer = wxGridSizer(1, num, 0, 0)
for i in range(MAX_TEXTS):
self.gps[i].SetSize((-1, -1))
if i < num:
self.gps[i].Show()
sizer.AddWindow(self.gps[i], 1, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 3)
else:
self.gps[i].Hide()
self.SetSizer(sizer)
sizer.SetSizeHints(self)
self.Layout()
self.GetParent().Layout()
def _initHeaders(self, parent):
gps = []
sizer = wxBoxSizer(wxHORIZONTAL)
for i in range(MAX_TEXTS):
item1 = wxStaticText( self, -1, "Text %d" % i, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE|wxST_NO_AUTORESIZE)
sizer.AddWindow( item1, 1, wxALIGN_CENTRE|wxLEFT|wxRIGHT, 3)
gps.append(item1)
return sizer, gps
class HeadingFrame(wxFrame):
"""Displays a panel of text headers.
The left part of the frame receives left- and right clicks which
decreased and increases the number of text headers displayed respectively.
"""
def __init__(self, parent):
wxFrame.__init__(self, parent, -1, "Heading Frame")
self.num = MAX_TEXTS
self.sizer = wxBoxSizer(wxHORIZONTAL)
self.th = TextHeadings(self)
self.sizer.AddSpacer( 20, 20, 0, wxALIGN_CENTRE|wxALL, 5 )
self.sizer.AddWindow( self.th, 1, wxALIGN_CENTRE|wxALL, 5 )
self.SetAutoLayout(true)
self.SetSizer(self.sizer)
self.sizer.Fit(self)
self.sizer.SetSizeHints( self )
EVT_LEFT_DOWN(self, self.LeftDown)
EVT_RIGHT_DOWN(self, self.RightDown)
def LeftDown(self, event):
if self.num > 1:
self.num -= 1
self.adjustWindow()
def RightDown(self, event):
if self.num < MAX_TEXTS:
self.num += 1
self.adjustWindow()
def adjustWindow(self):
print "Showing %d texts" % self.num
self.th.layoutHeaders(self.num)
self.printWinInfo(self)
def printWinInfo(self, win, indent=0):
methods = ['GetBestSize', 'GetSize', 'GetPosition']
print "%s-- %s --" % (' ' * indent, `win`)
for m in methods:
func = getattr(win, m)
ret = func()
print "%s%s: %s" % (' ' * indent, m, ret)
for c in win.GetChildren():
self.printWinInfo(c, indent+4)
if __name__ == '__main__':
app = wxPySimpleApp()
frame = HeadingFrame(None)
frame.Show(True)
app.MainLoop()
--------------------------------------------------------------------
--
- Michael Krause
- Email michael@krause-software.de