Recently I replaced the interface with vertical panedwindow. I created a
panedwindow and added both upper and lower frames. I realized the change
of widget size of lower frame no longer result change of the frame, or
the panned frame. If a widget in the lower frame grows taller, the
widgets on the bottom of the frame simply flow out of the view-port,
thus users cannot access them.
I think of upon changing of a widget height, either adjust
pannedwindow's separator to shift it upward, or enlarge the whole
interface. How else would you do?
Here is how I tried and failed:
For that to work I need to tell how much height is needed after the change.
I thought I could use the difference of [winfo reqheight .paned.lower]
and [winfo height .paned.lower] as the need to increase height, and
surprisingly find this: when a child widget is smaller, reqheight is
smaller than height; when a child widget is taller, [winfo reqheight] is
equal to [winfo height] but never more than it. Even when part of the
widget already flow out of view-port, [winfo reqheight] is still equal
to, not larger than, [winfo height]. So this is a dead-end.
After some time now I am able to answer my own question.
There doesn't seems to be a way to tell panedwindow to either change its
own size or shift the sash(es) when one of the pane changes its frame
size. This has to be done with a BIND event call.
The idea is simple, to find the difference of [winfo reqheight] and
[winfo height] and move the sashes according to the difference. The
following code has an additional logic that only enlarges lower pan but
never shrinks it.
.panedwindow add .panedwindow.pane1 -orient vertical
bind .panedwindow.pane1 <Configure> {
if { [winfo reqheight .panedwindow.pane1] >
[winfo height .panedwindow.pane1] } {
foreach {x y} [.panedwindow sash coord 0] {
[.f select].panedwindow sash place 0 $x [expr $y - ( \
[winfo reqheight .panedwindow.pane1] - \
[winfo height .panedwindow.pane1] ) ]
}
}
}
The above code is not generic: I found if a child frame change its size
and trigger a <Configure> event, the parent frame doesn't trigger the
same event, so one have to bind the event to the inner-most frame, which
is often not only one level deep as .panedwindow.pane1 of the example.
P.S. I posted a previous post saying reqheight and height return value
seems not reasonable. That post is mistaken: the error is due to UI is
by nature async and I obtained the height values before the frame size
changed. If request value in <Configure> event like in the above
example, the height value is obtained after frame size change thus correct.
Hi Zhang,
you can restrict, that the panes shrink below a predefined size. That
may be a compromise.
set f [frame .f]
set pw [panedwindow $f.pw -orient vertical]
set f1 [frame $pw.f1 -background red -width 10 -height 10]
set f2 [frame $pw.f2 -background green]
$pw add $f1
$pw add $f2
$pw paneconfigure $f1 -minsize 100
pack $pw -expand 1 -fill both
pack $f -expand 1 -fill both
Not every window class propagates size changes,
scrollable windows do not normally propagate.
> P.S. I posted a previous post saying reqheight and height return value
> seems not reasonable. That post is mistaken: the error is due to UI is
> by nature async and I obtained the height values before the frame size
> changed. If request value in <Configure> event like in the above
> example, the height value is obtained after frame size change thus correct.
width:1 and height:1 indicates this situation...
actual ismapped should reflect this. You can avoid
this situation by using the <Map> event in order
to bind on the <Configure> event--asynchronous of course.
The built-in panedwindow geometry manager is a crippled
grid geometry manager(reimplemented); why not
using "grid" in your layout?
-roger
The manual says panedwindow allows me to build applications with panes
and offer a handle the users can drag and change size of panes, so if a
user wants the left pane larger at the cost of right pane smaller, she
can do so with drag and drop, I don't see this can be done with grid, or
can it be done?
Thanks.