Arranging that a wxpython window inherits its size sensibly from its contents
===

I've written my first wxpython application and it works fine, but I ran into difficulties in an arranging that the (one and only) window be sized properly. The  panel contains an hbox, that in turn contains a FlexGridSizer, that in turn contains mainly 6 TextCtrl's. The tutorials I have read seemd to focus on setting sizes manually. What I would really like to do is to have the TextCtrl's work out what size they should be to contain 3 characters from a given font (say "WWW"), and that that in turn should automatically determine the size of the FlexGridSizer and the main window. I don't need to worry about resizing the layout (so maybe the Sizer isn't necessary?), I just want the sizes to be determined automatically and not by me putting magic constants into the program.

Code


    #!/usr/bin/env python
    # encoding: utf-8
    """
    NamesGUI.py
    """

    import wx
    from names_as_vs import name_sum, name_mult

    NAME_SIZE = 35

    class MyForm(wx.Frame):
    	def __init__(self, parent,title):
    		wx.Frame.__init__(self,parent,title=title,size=(405,200))
    		
    		self.default_init_UI()
    		self.init_UI()
    		self.Show()
    		
    	def default_init_UI(self):
    		"""Do all the standard UI stuff"""
    		file_menu = wx.Menu()
    		menuAbout = file_menu.Append(wx.ID_ABOUT,"About\tCtrl-A")
    		menuExit = file_menu.Append(wx.ID_EXIT,"Quit\tCtrl-Q")
    		
    		menu_bar = wx.MenuBar()
    		menu_bar.Append(file_menu,"File")
    		self.SetMenuBar(menu_bar)
    		
    		self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)
    		self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
    	
    	def init_UI(self):
    		"""Particular UI setup for this program"""
    		
    		hbox = wx.BoxSizer(wx.HORIZONTAL)
    		panel = wx.Panel(self)
    		fgs = wx.FlexGridSizer(2,5,9,9)
    		
    		fixed_elts_args = {"size":(30,70)}
    		plus = wx.StaticText(panel, label="+", **fixed_elts_args)
    		times = wx.StaticText(panel, label=".",**fixed_elts_args)
    		
    		equals1 = wx.Button(panel, label="=", **fixed_elts_args)
    		equals2 = wx.Button(panel, label="=", **fixed_elts_args)
    		equals1.Bind(wx.EVT_BUTTON, self.compute_sum)
    		equals2.Bind(wx.EVT_BUTTON, self.compute_mult)
    		
    		font = wx.Font(48,wx.ROMAN,wx.NORMAL,wx.NORMAL)
    		text_ctrl_args = {"size":(95,70)}
    		self.summand1 = wx.TextCtrl(panel, **text_ctrl_args)
    		self.summand2 = wx.TextCtrl(panel, **text_ctrl_args)
    		self.scalar = wx.TextCtrl(panel, **text_ctrl_args)
    		self.multiplicand = wx.TextCtrl(panel, **text_ctrl_args)
    		self.sum_result = wx.TextCtrl(panel, style = wx.TE_READONLY, **text_ctrl_args)
    		self.mult_result = wx.TextCtrl(panel, style = wx.TE_READONLY,     **text_ctrl_args)
		
    		for ctrl in (plus,times,equals1,equals2,self.summand1,self.summand2,
				    self.scalar,self.multiplicand,self.sum_result,self.mult_result):
    			ctrl.SetFont(font)
    		
    		fgs.AddMany([ 
    		self.summand1,plus,self.summand2,equals1,self.sum_result,
    		self.scalar,times,self.multiplicand,equals2,self.mult_result
    			])
    		
    		hbox.Add(fgs, proportion=1, flag= wx.ALL, border=15)
    		panel.SetSizer(hbox)
    		
    	def OnAbout(self,e):
		dlg = wx.MessageDialog(self, "A GUI implementation of 815 as a vector space",     "About 815 as a vector space", wx.OK)
    		dlg.ShowModal() # Shows it
    		dlg.Destroy() # finally destroy it when finished.
    	
    	def OnExit(self,e):
    		self.Close(True)  # Close the frame.
    	
    	def compute_sum(self,e):
    		"""Computes the sum of the names in summand1 and summand2 and displays the result in self.sum_result"""
    		n1 = self.summand1.GetValue()
    		n2 = self.summand2.GetValue()
    		self.sum_result.SetValue(name_sum(n1,n2))
    	
    	def compute_mult(self,e):
    		"""
    		Computes the scalar multiple of the name in multiplicand by the scalar in scalar and displays the result in self.mult_result
    		"""
    		n = self.multiplicand.GetValue()
    		lamb = self.scalar.GetValue()
    		self.mult_result.SetValue(name_mult(lamb,n))
    
    	
    def main():
    	app = wx.App(False)
    	frame = MyForm(None,"815 as a vector space")
    	app.MainLoop()


    if __name__ == '__main__':
    	main()
