Any help or pointers would be appreciated.
Thanks,
James Bigler
Yes, you discovered what I did eventually. The OnSize event was causing part of
the problem. I needed to add event.Skip(True) to make it work on making it bigger.
I still can't make it smaller than the initial size, however. I even tried to
change the minimum size after the window was shown, but that didn't have an effect.
def OnSize(self, event):
if (not self.panel.minSizeSet):
self.panel.SetMinSize(wx.Size(20,20))
self.panel.minSizeSet = True
self.SetStatusText("Size = %s" % (self.panel.GetSize(),) )
event.Skip(True)
So I want the panel to be a certain initial size, but I want to be able to make
it bigger or smaller afterwards.
Thanks,
James
> Just realized I forgot to attach the demo code.
>
> James
Here is some modified code that I think does what you want:
---------------
import wx
class MyApp(wx.App):
def OnInit(self):
frame = Frame(parent=None, title=\'Resize Panel\')
frame.Show()
self.SetTopWindow(frame)
return True
class Frame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent=parent, title=title)
# Setup menu bar
menuBar = wx.MenuBar()
menu1 = wx.Menu()
self.Bind(wx.EVT_MENU, self.OnQuit, menu1.Append(wx.NewId(),
\"&Quit\"))
menuBar.Append(menu1, \"&File\")
menu2 = wx.Menu()
self.Bind(wx.EVT_MENU, self.OnAbout, menu2.Append(wx.NewId(),
\"About Me\"))
menuBar.Append(menu2, \"&Help\")
self.SetMenuBar(menuBar)
# Create status bar
self.CreateStatusBar()
self.SetStatusText(\"Welcome to wxPython!\")
# Create the panel
self.panel = wx.Panel(self, -1, size=wx.Size(300,400))
self.panel.SetBackgroundColour(wx.NamedColor(\"green\"))
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(self.panel, 1, wx.EXPAND)
self.SetSizerAndFit(box)
print \"Min Size = %s\" % self.panel.GetMinSize()
print \"Max Size = %s\" % self.panel.GetMaxSize()
print \"Best Size = %s\" % self.panel.GetBestSize()
def OnQuit(self, event):
self.Close()
def OnAbout(self, event):
wx.MessageBox(\"This is a test program to show how to resize
the main panel. I want the green panel to change size when the screen
is resized bigger and smaller than the original. \",
\"About Me\", wx.OK | wx.ICON_INFORMATION, self)
if __name__ == \'__main__\':
app = MyApp(False)
app.MainLoop()
-----------------
Regards,
Ray Smith
http://RaymondSmith.com
> I still can\'t make it smaller than the initial size, however. I even
> tried to change the minimum size after the window was shown, but that
> didn\'t have an effect.
>
> def OnSize(self, event):
> if (not self.panel.minSizeSet):
> self.panel.SetMinSize(wx.Size(20,20))
> self.panel.minSizeSet = True
>
> self.SetStatusText(\"Size = %s\" % (self.panel.GetSize(),) )
> event.Skip(True)
>
> So I want the panel to be a certain initial size, but I want to be able
> to make it bigger or smaller afterwards.
Hi James,
One way is to set the frame to a default size and don\'t do the:
self.SetSizerAndFit(box)
See code below:
-----------
import wx
class MyApp(wx.App):
def OnInit(self):
frame = Frame(parent=None, title=\'Resize Panel\')
frame.Show()
self.SetTopWindow(frame)
return True
class Frame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent=parent, title=title, size=(300,400))
# Setup menu bar
menuBar = wx.MenuBar()
menu1 = wx.Menu()
self.Bind(wx.EVT_MENU, self.OnQuit, menu1.Append(wx.NewId(),
\"&Quit\"))
menuBar.Append(menu1, \"&File\")
menu2 = wx.Menu()
self.Bind(wx.EVT_MENU, self.OnAbout, menu2.Append(wx.NewId(),
\"About Me\"))
menuBar.Append(menu2, \"&Help\")
self.SetMenuBar(menuBar)
# Create status bar
self.CreateStatusBar()
self.SetStatusText(\"Welcome to wxPython!\")
# Create the panel
self.panel = wx.Panel(self, -1)
self.panel.SetBackgroundColour(\"green\")
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(self.panel, 1, wx.EXPAND)
# !!! This resizes the frame !!!
#self.SetSizerAndFit(box)
print \"Min Size = %s\" % self.panel.GetMinSize()
print \"Max Size = %s\" % self.panel.GetMaxSize()
print \"Best Size = %s\" % self.panel.GetBestSize()
def OnQuit(self, event):
self.Close()
def OnAbout(self, event):
wx.MessageBox(\"This is a test program to show how to resize
the main panel. I want the green panel to change size when the screen
is resized bigger and smaller than the original. \",
\"About Me\", wx.OK | wx.ICON_INFORMATION, self)
if __name__ == \'__main__\':
app = MyApp(False)
app.MainLoop()
----------------
Regards,
Ray Smith
http://RaymondSmith.com
..SNIP CODE EXAMPLE..
This works OK, but then the panel isn't the right size because of the space
taken by the menu and status bar (and perhaps additional things in the future).
I really need the panel to be a certain size to start off with, but be able to
be resized bigger and *smaller* after the initial layout.
Thanks,
James
...SNIP CODE...
# Create the panel
self.panel = wx.Panel(self, -1, size=(300,400))
self.panel.SetBackgroundColour("green")
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(self.panel, 1, wx.EXPAND)
# !!! This resizes panel !!!
#self.SetSizerAndFit(box)
...SNIP CODE...
I tried you code and the panel doesn't start off with the right size. Plus the
status bar doesn't appear until I make the window long enough (looks like to be
around the requested height of the panel).
What I don't get is why the sizer forces the min size to be (300,400). I even
tried to force it to be smaller, but the sizer overrides it somehow.
Thanks,
James
Hi James,
I added:
print \\\"Size = %s\\\" % self.panel.GetSize()
and got the results:
Size = (300, 400)
did you get something else?
The status bar is displayed as soon as the program starts on my PC\'s
(WinXP and Win2000 using Python 2.4 wxPython 2.6.3.2).
I have attached your program with my mods. Previously the inline
version was formatted poorly.
Regards,
Ray Smith
I got out that size, but wxPython doesn't size the panel in the window properly.
I've attached some images of what it looks like originally and after I resize
it a bit.
> The status bar is displayed as soon as the program starts on my PC\'s
> (WinXP and Win2000 using Python 2.4 wxPython 2.6.3.2).
I'm using Ubuntu 5.10 with Python 2.4.2, wxPython (GTK) 2.6.1.1. That's pretty
close to what you are using, so maybe this is a GTK issue?
> I have attached your program with my mods. Previously the inline
> version was formatted poorly.
I was able to run the files properly after I removed all the '\'s in front of
the quotes.
Thanks,
James
BTW, I really appreciate your help with this. I've been fighting this for days now.
> This works OK, but then the panel isn\'t the right size because of the
> space taken by the menu and status bar (and perhaps additional things
> in the future).
>
> I really need the panel to be a certain size to start off with, but be
> able to be resized bigger and *smaller* after the initial layout.
Hi James,
Sorry, you should be able to set the size of the panel in the same way:
See code:
-------------
import wx
class MyApp(wx.App):
def OnInit(self):
frame = Frame(parent=None, title=\'Resize Panel\')
frame.Show()
self.SetTopWindow(frame)
return True
class Frame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent=parent, title=title)
# Setup menu bar
menuBar = wx.MenuBar()
menu1 = wx.Menu()
self.Bind(wx.EVT_MENU, self.OnQuit, menu1.Append(wx.NewId(),
\"&Quit\"))
menuBar.Append(menu1, \"&File\")
menu2 = wx.Menu()
self.Bind(wx.EVT_MENU, self.OnAbout, menu2.Append(wx.NewId(),
\"About Me\"))
menuBar.Append(menu2, \"&Help\")
self.SetMenuBar(menuBar)
# Create status bar
self.CreateStatusBar()
self.SetStatusText(\"Welcome to wxPython!\")
# Create the panel
self.panel = wx.Panel(self, -1, size=(300,400))
self.panel.SetBackgroundColour(\"green\")
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(self.panel, 1, wx.EXPAND)
# !!! This resizes panel !!!
#self.SetSizerAndFit(box)
print \"Min Size = %s\" % self.panel.GetMinSize()
print \"Max Size = %s\" % self.panel.GetMaxSize()
print \"Best Size = %s\" % self.panel.GetBestSize()
print \"Size = %s\" % self.panel.GetSize()
def OnQuit(self, event):
This is the size before the sizer does a layout. If you look at the
size after the frame has been shown and the layout happens then you'll
see the problem James is having. Without the SetSizer* call in your
sample the default frame size is being used and so the panel is being
resized in the first layout.
To address the other problems there are a couple things that needs to be
understood about sizers and default sizes.
First, SetSizerAndFit is a convenience function that simply calls
self.SetSizer(sizer) and sizer.SetSizeHints(self), so when you call that
with the frame you are setting the min size of the frame based on the
current minsize needed by the sizer, so that is why the frame can't be
resized smaller. So changing that to just self.SetSizer and a separate
call to self.Fit will set the initial size correctly based on the
sizer's min size, but still allow the frame to get smaller.
Second, when a sizer calculates the space it needs it calls the
GetSBestFittingSize method on each widget that will return a size based
on the widget's min size (if set) and a calculated best size. But for
things like the panel which has no children, no sizer, and no set
minsize there is no way to calculate a best size so the current size is
used instead. For widgets that will have a flexible size in the sizer
this means that as soon as the sizer changes the size larger, then the
best size is larger and the sizer may not make it smaller (depending on
the sizer parameters.) Also, for most widgets passing a size to the
constructor will set the min size to that value.
So in the case of this example where you want the initial size to not be
the min size, you need to set the initial size in some other way than by
letting the sizer do it. See attached sample for one way to do it.
--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!
So, one of the things I had to note about your comment is that it
creates a min size for the *frame*. I was changing the min size of the
panel, but not changing the min size of the frame. Because of this, I
couldn't size the panel down.
> Second, when a sizer calculates the space it needs it calls the
> GetSBestFittingSize method on each widget that will return a size based
> on the widget's min size (if set) and a calculated best size. But for
> things like the panel which has no children, no sizer, and no set
> minsize there is no way to calculate a best size so the current size is
> used instead. For widgets that will have a flexible size in the sizer
> this means that as soon as the sizer changes the size larger, then the
> best size is larger and the sizer may not make it smaller (depending on
> the sizer parameters.) Also, for most widgets passing a size to the
> constructor will set the min size to that value.
>
> So in the case of this example where you want the initial size to not be
> the min size, you need to set the initial size in some other way than by
> letting the sizer do it. See attached sample for one way to do it.
The problem with this is that it did weird things when I had a
wxGLCanvas in the panel. Something would cause a SIZE event and it
would pop down to the min size of (20, 20).
Here's the relevant block of code that sets the size of the panel, does
a fit to get everything the correct size in the beginning and then
changes the min size of the panel and frame.
# Create the panel
self.panel = wx.Panel(self, -1)
self.panel.SetBackgroundColour(wx.NamedColor("green"))
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(self.panel, 1, wx.EXPAND)
# Set the initial sizes I want
self.panel.SetSize((300, 400))
self.SetSizerAndFit(box)
# Now fix the min sizes of the panel and frame
self.panel.SetMinSize((20,20))
self.SetMinSize(self.GetSize() - self.panel.GetSize()
+ self.panel.GetMinSize())
This also does the right thing when I have a wxGLCanvas inside the
panel. I've attached the latest code.
Thank you Robin and Ray!
James