ttk::panedwindow

Difference between version 24 and 25 - Previous - Next
[['''`[http://www.tcl.tk/man/tcl/TkCmd/ttk_panedwindow.htm%|%ttk::panedwindow]`''']
creates and manipulates [ttk] [paned window] [widget%|%widgets].



** See Also **

   [paned window]:   




** Documentation **

   [http://www.tcl.tk/man/tcl/TkCmd/ttk_panedwindow.htm%|%official reference]:   

See [Changing Widget Colors] for style options


** Discussion **


***Resize when client window size changes***

[SPB] 2015-09-14: I wish to have the "-stretch last" or "-stretch never"
behaviour of tk::panedwindow, but I cannot figure out how one might do that with
ttk::panedwindow. Any suggestions? (My specific problem is that I have a frame F
packed into the bottom pane of my panedwindow, that I wish to always take up
solely the space of the frame, unless the user moves the sash. Setting the weight
to 0 fails, as the pane acquires no space at all and the frame F remains invisible when
added to the PW. Setting non-zero weights causes extra (empty) space to become
proportionally allocated to F, when I don't want it to get any extra space at all.)
Is there a way to have a pane of a ttk::panedwindow to allocate the space of
the frame it contains, but no more than that? Thank you!

[HaO] Joe English answered on the core list [http://code.activestate.com/lists/tcl-core/14879/]:

ttk::panedwindow only honors geometry requests from slaves
if they are currently unmapped.  IIRC, the core panedwindow
works the same way.

I do not recall the exact details, but doing otherwise led to
erratic behavior when the user dragged the sash, especially
in combination with ill-behaved megawidgets. 

If you unmap and remap the pane after adding subwindows,
that will retrigger geometry propagation.

----


***Ordered list of managed slaves***


[WHD] 2010-04-14: Is there a way to get a list of the names of the managed
subwindows in index order?  I can refer to managed subwindows from 0 to end,
but I don't see any way in the interface to determine how many managed windows
there are, nor the order in which they are stacked.  [winfo children] returns
the children of the panedwindow in the order of creation, which can be very
different.

[MG]: The ttk::panedwindow has some undocumented subcommands, the one you want
is `$panedWindow panes`:

======none
(bin) 1 % pack [ttk::panedwindow .pw]
(bin) 2 % .pw foobar
bad command "foobar": must be add, configure, cget, forget, identify, insert, instate, pane, panes, sashpos, or state
(bin) 3 % set tcl_patchLevel
8.5.7

$panedWindow panes                            ;# returns a list of all widgets being used as panes, in order
$panedWindow add $widget [-option value ...]  ;# seems to be an alias for $panedWindow insert end $widget [-option value ...]
======

----

[MHo] 2008-04-09: Does someone know if and how it's possible to determine the
dimension of a pane inside a panedwindow? I have a canvas inside a pane that
holds an image. If resizing / maximizing the top-level windows, everything
should grow to use the extra space. But the pane itself says it is has the
dimension '''1x1''', and the canvas stays as its initial size (if I don't
specify such initial size, something else goes wrong that is beyond the scope
of this question...).

[MG]: I've noticed with this (and other Tile widgets) in Windows / Tk 8.5 that
there's a delay before sizes and things fully update - calling [update] and/or
[update idletasks] doesn't resolve the problem. I've had to resort to doing
something like

======
$widget add $foo
after 25 [list doStuffWith $widget]
======

to give the widgets time to update their sizes and report the correct ones
back. See if that resolves the problem? In your case, [winfo] width and [winfo
height] on the canvas may work, too?



** Create a Custom Sash Handle bar**

In the default theme the sash handle bar is empty. So it is not obvious that it
is a panedwindow. This little piece of code creates a new style for the
panedwindow which as a Firefox-like sash handle bar.

======
image create photo img:sash -data {
R0lGODlhBQB5AKECADMzM9TQyP///////yH+EUNyZWF0ZWQgd2l0aCBHSU1QACH5BAEKAAMALAAA
AAAFAHkAAAJOjA95y+0LUAxpUkufboLh1UFPiIyeKTqk8R1rpp5xysk1zbytoaPl/LsFczYiDlRE
Hl1J5pLXhD4DPSDLd7XChFnudgO2KC5izA6sqTQKADs=
}

ttk::style element create Sash.xsash image \
        [list img:sash ] \
        -border {1 1} -sticky ew -padding {1 1}

ttk::style layout TPanedwindow {
        Sash.xsash
}
======
Also see [Custom sash handle for panedwindow]

** Example **

======
package require Ttk

# ttk::setTheme clam

set xf [ttk::frame .f]
set pw [ttk::panedwindow .f.pw -orient horizontal ]

ttk::frame $pw.f1
ttk::label $pw.f1.l -text "Frame 1"
pack $pw.f1.l

ttk::frame $pw.f2
ttk::label $pw.f2.l -text "Frame 2"
pack $pw.f2.l

$pw add $pw.f1
$pw add $pw.f2

pack $pw -expand 1 -fill both
pack $xf -expand 1 -fill both
======

-----

***MinSize***

[HaO] 2016-05-19: I asked on clt "ttk::panedwindow minheight and sash" about a minimum size of a managed window.
For me, it is often not clear to the user that:
   *   there is a pane people may drag
   *   there are two windows when the sash is at one of the borders.
Unfortunately, the sash may move to the border by a window resize or at application statup.
The user may not be the cause for the hidden panes.

I tried the upper "sash icon". It did not work for me, as the sash icon itself was often hidden on resizing.

Within the clt thread, Brad Lanam supplied the following script which resets the sas to position 30 if dragged to 0:

======
proc dosash { w args } {
  set sp [.p sashpos 0]
  if { $sp < 20 } {
    .p sashpos 0 30
  }
}

proc conf { w args } {
}

proc out { f } {
  .p forget $f
  if { [llength [.p panes]] == 0 } {
    wm withdraw .
  }
  update
  wm manage $f
  bind $f <ButtonRelease-1> [list in $f]
  $f configure -background pink
}

proc in { f } {
  wm forget $f
  .p add $f
  wm deiconify .
  bind $f <ButtonRelease-1> [list out $f]
  $f configure -background [string trim $f .]
}

ttk::style configure TPanedwindow \
    -background blue
ttk::style configure Sash -sashthickness 20

ttk::panedwindow .p -orient horizontal -style TPanedwindow
pack .p -expand true -fill both
pack propagate .p false
frame .cyan -background cyan -height 200 -width 200
ttk::label .cyan.txt -text {This is frame one.}
pack .cyan.txt
frame .yellow -background yellow -height 200 -width 200
ttk::label .yellow.txt -text {This is frame two.}
pack .yellow.txt
.cyan configure -height 200 -width 200
.yellow configure -height 200 -width 200
.p add .cyan -weight 1
.p add .yellow -weight 1

bind .cyan <ButtonRelease-1> [list out .cyan]
bind .yellow <ButtonRelease-1> [list out .yellow]
bind .cyan <ButtonRelease-2> [list .cyan configure -width 420]
bind .yellow <ButtonRelease-2> [list .yellow configure -width 420]
bind .p <Configure> [list conf %W]
bind .p <ButtonRelease-1> [list dosash %W]
bind .cyan <Configure> [list conf %W]
bind .yellow <Configure> [list conf %W]
======

-----

***Lock pane***

[PO] 2017-05-12: Had the need to lock panes. Here is a solution using [bindtags]:
======
package require Tk

proc LockPane { w onOff } {
    if { $onOff } {
        bindtags $w { $w . all }
    } else {
        bindtags $w { $w TPanedwindow . all }
    }
}

set fr .fr
frame $fr
pack $fr -expand 1 -fill both

set vpane $fr.vpane
ttk::panedwindow $vpane -orient vertical
pack $vpane -side top -expand 1 -fill both

set tf $vpane.tfr
set bf $vpane.bfr
frame $tf -bg red
frame $bf -bg green
pack $tf -expand 1 -fill both
pack $bf -expand 1 -fill both

$vpane add $tf
$vpane add $bf

set hpane $bf.hpane
ttk::panedwindow $hpane -orient horizontal
pack $hpane -side top -expand 1 -fill both

set lf $hpane.lfr
set rf $hpane.rfr
frame $lf -bg yellow
frame $rf -bg magenta
pack $lf -expand 1 -fill both
pack $rf -expand 1 -fill both

$hpane add $lf
$hpane add $rf
 
button $tf.b1 -text "Lock vertical"   -command "LockPane $vpane true"
button $tf.b2 -text "Lock horizontal" -command "LockPane $hpane true"
pack $tf.b1 $tf.b2 -fill x
button $lf.b1 -text "Unlock vertical"   -command "LockPane $vpane false"
button $lf.b2 -text "Unlock horizontal" -command "LockPane $hpane false"
pack $lf.b1 $lf.b2 -fill x

wm minsize . 300 200
update
$hpane sashpos 0 150
$vpane sashpos 0 100
======


<<categories>> Widget | paned window