I am still trying to get comfortable with wxPython... A lot is making sense but I am still having some trouble in seeing what events to hook to what methods and what methods on what widgets to call to get desired behavior. I am also kinda fuzzy on the relationship between a sizer and it's parent frame.
For example, in the first example below (modified from listing 11.3, pg 332 of Noel & Robin's book), there is a single call to Fit() and no explicit binding of wx.EVT_SIZE, no explicit request to have the sizer lay itself out, etc. but this sizer if obviously responding to resize events. This is a little confusing to me.
In the second example below, I have a simple "Hello, World!" sort of app where the behavior I would like to achieve is that after selecting a different font, either the font is rendered in the middle of the (150, 100) frame if it fits, respecting the borders, or the frame is resized to just fit the bigger text. I would also like to get the frame to refuse to resize smaller than (150, 100), or smaller than the preferred size of the text (with borders), whichever is larger. The code as it is below causes the sizer to lay out again and the new bigger text is re-centered but this does not affect the Frame size. Calling Fit() on the Panel or Frame does not resize as I would expect, so I'm not quite seeing where to go from here to achieve that.
Could someone help me out and clue me into the missing pieces here and explain a little more about the interaction between a frame or panel and its sizer (i.e., minimum sizes and who's controlling who, who resizes to accommodate who and how you control all that)?
Thanks for taking the time to read my post! Code is below.
-ej
#!/usr/bin/env python
"""
First Example - no explicit call to resize or Layout() or use of wx.EVT_SIZE, etc. needed to
keep label centered in frame - magic?
"""
import wx
class Frame(wx.Frame):
def __init__(self, parent=None, id=-1,
pos=wx.DefaultPosition, title='Hello, wxPython!'):
wx.Frame.__init__(self, parent, id, title, pos, (150, 100))
panel = wx.Panel(self, -1)
panel.SetBackgroundColour('white')
sizer = wx.GridSizer(rows=1, cols=1, hgap=0, vgap=0)
panel.SetSizer(sizer)
text = wx.StaticText(panel, -1, title, (30, 30))
sizer.Add(text, 0, wx.ALIGN_CENTER)
panel.Fit()
class App(wx.App):
def OnInit(self):
self.frame = Frame()
self.frame.Show()
self.SetTopWindow(self.frame)
return True
if __name__ == '__main__':
app = App(redirect=False)
app.MainLoop()
#!/usr/bin/env python
"my sample app I want to get to meet the specs explained above"
import wx
from wx.lib.stattext import GenStaticText
···
#=======================================================================
class Frame(wx.Frame):
def __init__(self, parent=None, id=-1,
pos=wx.DefaultPosition, title='Hello, wxPython!'):
wx.Frame.__init__(self, parent, id, title, pos, (150, 100))
panel = wx.Panel(self, -1)
panel.SetBackgroundColour('white')
sizer = wx.GridSizer(rows=1, cols=1, hgap=10, vgap=10)
panel.SetSizer(sizer)
text = GenStaticText(panel, -1, title, (30, 30))
sizer.Add(text, 0, wx.ALIGN_CENTER)
self.text = text
self.sizer = sizer
self.panel = panel
#=======================================================================
#=======================================================================
class App(wx.App):
def OnInit(self):
self.frame = Frame()
self.setup_menus()
self.frame.Show()
self.SetTopWindow(self.frame)
return True
def setup_menus(self):
menu_bar = wx.MenuBar()
file_menu = wx.Menu()
quit_item = file_menu.Append(-1, '&Quit', 'Quit')
self.frame.Bind(wx.EVT_MENU, self.OnCloseWindow, quit_item)
config_menu = wx.Menu()
font_item = config_menu.Append(-1, 'Choose Font', 'Choose_Font')
self.frame.Bind(wx.EVT_MENU, self.OnChooseFont, font_item)
menu_bar.Append(file_menu, '&File')
menu_bar.Append(config_menu, '&Configure')
self.frame.SetMenuBar(menu_bar)
def OnCloseWindow(self, event):
self.frame.Destroy()
def OnChooseFont(self, event):
dialog = wx.FontDialog(None, wx.FontData())
if dialog.ShowModal() == wx.ID_OK:
data = dialog.GetFontData()
font = data.GetChosenFont()
font_name = font.GetFaceName()
size = font.GetPointSize()
color = data.GetColour()
print
print "chosen font: %s, %d, %s" % (font_name, size, color)
self.frame.text.SetFont(font)
# causes text to be centered in frame, but frame too small
self.frame.sizer.Layout()
# These attempts don't get the Frame to accomodate new text size
# self.frame.Fit()
# self.frame.panel.Fit()
# self.frame.SetSize(self.frame.sizer.GetSize())
dialog.Destroy()
#=======================================================================
#-----------------------------------------------------------------------
def main():
app = App(redirect=False)
app.MainLoop()
#-----------------------------------------------------------------------
if __name__ == '__main__':
main()