Hi All,
I asked about this before and Robin replied on March 21, 2011. I’m not
sure how to reference a previous post, but you can find it by searching
for my last name ‘soher’. It seems to be a pretty unique set of 5 chars
and I post infrequently.
I’m doing a cut and paste of what he said just in case it is useful to
folks. I’ve also attached my original screen shot and example
program.
Bottom line was that in the end I just had to find the right upper level
Panel to call layout on to get everything below it to resize properly. It
was not always successful with the parent Panel, sometimes it needed to
be 2-3 more levels up. And that was a bit of a pain.
Regards,
Brian.
In reply to
this post by Brian J. Soher
Thanks very much for the the suggestions. I’ve attached an improved
example, that also functions properly. Sort of. If you have time to
take
a look further, I’d appreciate any suggestions.
To summarize: My overall problem is that I want a
“dynamic” (group of
Hide()/Show()) panels in the middle of a pretty complex GUI layout.
The
dynamic panel should resize larger if a large panel (say three lines
of
widgets) is Show()n or similarly shrink if a smaller panel (say one
line
of widgets) is Show()n.
Any additional widgets located below the dynamic panel (typically in
a
Sizer OR a Panel in a Sizer) should get shifted down or up as
appropriate (see attached PNG).
The solution I found had two steps (see attached example program -
version 2). First when the combo event is called, I GetBestSize() of
the
panel to be Show()n, I SetMinSize() and SetSize() of the parent
panel
that already contains the panel to be displayed. Last call Layout()
at
the Frame and at other panels at different levels. I find that the
application does not refresh properly if I just call Layout() at the
frame. If I call it at the frame and then manually resize the frame
it
refreshes OK after the manual resize. However, by calling Layout()
at
the Frame, then the TopPanel(), the application refreshes properly.
In my larger application, with more sub-levels, I find that calling
Layout() at the Frame plus 2-3 sublevels seems to refresh properly
without needing a manual refresh.
«
[
hide part of quote]
Ok, this is a slightly different problem than I had thought from your
original message. Here is the key to understanding why your
workaround
works and a Layout() at the toplevel does not: Automatic layouts
normally only happen in the EVT_SIZE handler of a window. If
whatever
was changed did not require a change of size of some subwindow, then a
Layout call on some window further up the containment hierarchy will not
need to change the size of that subwindow and so its Layout will not be
called and so the repositioning and resizing actions do not filter down
to the children of that subwindow. By calling Layout at someplace
other
than the top-level you are bypassing that optimization that could have
happened because the overall size of the subwindow did not need to
change.
Clear as mud? Using the WIT will help you diagnose things like this
if
you know to look for them.
http://wiki.
wxpython
.org/Widget_Inspection_Tool It will also help you
figure out where to surgically implant a Layout call because you can
experiment with the live widgets in your application from a PyCrust
shell.
Usually in situations like this one or two mid-hierarchy Layout()s will
take care of the problem and all is well, most of the time it is just
the level above the widgets that were changed or replaced that needs to
have the Layout done (unless you want the new minsize to filter all the
way up to do something like cause a resize of the frame, as I suggested
in my last mail.) In one uber-complex layout with a couple hundred
total widgets and about a dozen or so layers in the hierarchy I gave up
and did something like this:
widget = self.widgetThatWasChanged
while widget.GetParent():
widget =
widget.GetParent()
widget.Layout()
It works, but it is doing more work than needed to accomplish the
layout, so I only suggest it as a way to move on without driving
yourself to the point of setting your hair on fire and running out into
traffic.
In your test code I would say that your workaround is actually the
proper thing to do, not simply a workaround. That’s because it is
not
the contents of self (the frame) that have changed, but the contents of
self.PanelTop.
test_dynamic_example_v2.py (4.07 KB)
···
On 3/21/11 3:07 PM, bsoher wrote:
Robin Dunn
Software Craftsman
http://wxPython
.org
At 03:08 PM 6/24/2011, you wrote:
On 24-06-2011 19:55, Micah > Nordland wrote:
I had that same sort of problem. What you should do is call the
frame’s SendSizeEvent() method.
This will work the same as re-sizing the window.
not always.
Neither the suggestion of Mike, doesn’t work always.
The best way I found,
is to send a Layout command to the next higher panel.
btw, this is a very interesting question,
and I’m curious to answer of the master.
cheers,
Stef
–
Praising my Savior all the day long,
Micah Nordland
–
To unsubscribe, send email to
wxPython-users+unsubscribe@googlegroups.com
or visit
http://groups.google.com/group/wxPython-users?hl=en
–
To unsubscribe, send email to
wxPython-users+unsubscribe@googlegroups.com
or visit
http://groups.google.com/group/wxPython-users?hl=en