Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

adjust paned-window size to hold its content

121 views
Skip to first unread message

Zhang Weiwu

unread,
Dec 22, 2010, 11:46:17 AM12/22/10
to
Hello. I used to have an interface where one frame packed on top of
another, while the lower frame vary in height during user using it, due
to the change of size of its children.

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.

Zhang Weiwu

unread,
Dec 23, 2010, 9:47:54 PM12/23/10
to
On 12/23/2010 12:46 AM, Zhang Weiwu wrote:
> 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?

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.

hae

unread,
Dec 24, 2010, 3:44:08 AM12/24/10
to

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

Arndt Roger Schneider

unread,
Dec 24, 2010, 8:00:02 AM12/24/10
to
Zhang Weiwu schrieb:

> On 12/23/2010 12:46 AM, Zhang Weiwu wrote:
>
>>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?
>
>
> 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.
>

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

Zhang Weiwu

unread,
Apr 24, 2011, 5:18:34 AM4/24/11
to
On 12/24/2010 09:00 PM, Arndt Roger Schneider wrote:
>
> The built-in panedwindow geometry manager is a crippled
> grid geometry manager(reimplemented); why not
> using "grid" in your layout?

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.

0 new messages