Layout() causes wx.ListBox to change size + 2 random questions

Hello,

I’ve been struggling now for some time with a few problems which are purely cosmetic, however they still bother me a bit! The problems are illustrated in the attached script.

  1. In the script I’m using a GridBagSizer to position the widgets in the frame. I have a ListBox which spans two rows and is initially empty. Upon pressing the Load button, the ListBox is populated and everything looks fine. However afterwards when the Layout button is pressed, the size of the ListBox changes and messes up the whole screen. Is this a bug, or am I doing something wrong? Is there a way to make the ListBox keep the same size even when Layout() is called?

  2. My other question is regarding wx.Choice and wx.ComboBox. As can be seen from my example, the default size settings for these two are quiet different. wx.ComboBox seems to have a set large width regardless of what its value is, while the width of wx.Choice depends on its initial value. Is there a way to get the same size for all these widget on a page without having to explicitly give size=(x,y) in their definition? I know that in this case I could use flag=wx.EXPAND since they are in the same column, but I’m wondering regarding a more general case.

  3. Is there a command which resets a given GUI and sets the values of all the widgets back to the initial state as if the program has been just opened? Currently I’m resetting every widget one by one, but I was wondering if there is a smarter and quicker way to accomplish the same task.

Thanks a lot in advance for any help and suggestions.

#!/usr/bin/env python

import wx

class MyExampleClass(wx.Frame):

def init(self,parent,id):

  wx.Frame.__init__(self,parent,id)
  self.main_sizer = wx.GridBagSizer(hgap=10, vgap=10)

  self.example_listbox = wx.ListBox(self, -1, choices=[], style=wx.LB_ALWAYS_SB)
  load_list_btn = wx.Button(self, -1, label='Load')
  layout_btn = wx.Button(self, -1, label='Layout')

  self.main_sizer.Add(wx.StaticText(self, -1, label='This is an example'), pos=(0,0))
  self.main_sizer.Add(self.example_listbox, pos=(1,0), span=(2,1), flag=wx.EXPAND)
  self.main_sizer.Add(load_list_btn, pos=(1,1))
  self.main_sizer.Add(layout_btn, pos=(2,1))
  self.main_sizer.Add(wx.ComboBox(self, -1, value='example', choices=['example']), pos=(1,2))
  self.main_sizer.Add(wx.ComboBox(self, -1, value='longer example', choices=['longer example']), pos=(2,2))
  self.main_sizer.Add(wx.Choice(self, -1, choices=['example']), pos=(3,2))
  self.main_sizer.Add(wx.Choice(self, -1, choices=['longer example']), pos=(4,2))

  self.Bind(wx.EVT_BUTTON, self.load_values, load_list_btn)
  self.Bind(wx.EVT_BUTTON, self.frame_layout, layout_btn)

  self.SetSizer(self.main_sizer)
  self.main_sizer.Fit(self)

def load_values(self,event):
list_values = []
for n in range(6):
list_values.append('value ’ + str(n))
self.example_listbox.Set(list_values)

def frame_layout(self,event):
self.main_sizer.Layout()

if name==‘main’:
app=wx.App()
mainframe=MyExampleClass(parent=None,id=-1)
mainframe.Show()
app.MainLoop()

Hello,

I've been struggling now for some time with a few problems which are
purely cosmetic, however they still bother me a bit! The problems are
illustrated in the attached script.

1. In the script I'm using a GridBagSizer to position the widgets in the
frame. I have a ListBox which spans two rows and is initially empty.
Upon pressing the Load button, the ListBox is populated and everything
looks fine. However afterwards when the Layout button is pressed, the
size of the ListBox changes and messes up the whole screen. Is this a
bug, or am I doing something wrong? Is there a way to make the ListBox
keep the same size even when Layout() is called?

The ListBox's best size changes when you add content to it, and the Layout will use that new best size when calculating how to size and position all the widgets. If you don't want the listbox to adjust to its content then set its MinSize, that will override the calculated best size. Or you can have the listbox span more rows so when it changes size it will not cause rows to expand to accommodate it.

2. My other question is regarding wx.Choice and wx.ComboBox. As can be
seen from my example, the default size settings for these two are quiet
different. wx.ComboBox seems to have a set large width regardless of
what its value is, while the width of wx.Choice depends on its initial
value. Is there a way to get the same size for all these widget on a
page without having to explicitly give size=(x,y) in their definition? I
know that in this case I could use flag=wx.EXPAND since they are in the
same column, but I'm wondering regarding a more general case.

This is again related to the calculated best size of the widgets. They can all potentially have different algorithms for how they calculate that size, usually based on the nature of the widget, and is usually also influenced by the size of the current content of the widget. If you want to limit the size to a fixed size then you'll need to set the min size either in the constructor call or with SetMinSize. Or you could

BTW, this: http://wiki.wxpython.org/Widget_Inspection_Tool can help you diagnose and solve layout problems.

3. Is there a command which resets a given GUI and sets the values of
all the widgets back to the initial state as if the program has been
just opened? Currently I'm resetting every widget one by one, but I was
wondering if there is a smarter and quicker way to accomplish the same task.

No, there is no way to generalize that for every situation. It wouldn't be hard to add something like that in your own code however. For example you can assign a .initialValue attribute to all your widgets, and then write a function that does a recursive traversal of all widgets using GetChildren which checks for the presence of that attribute and if it is there then call the widget's SetValue with that value.

···

On 10/13/11 12:14 PM, G. Nikiforov wrote:

--
Robin Dunn
Software Craftsman