Ttk's labelframe widget.
Bryan Oakley 28-Feb-2008 Since there's a dearth of information available about tweaking ttk::styles and themes, I thought I'd share this bit of code. I'm finding that path to ttk enlightenment is a bit rocky, but view at the end of the trail is pretty nice.
For my immediate needs I was wanting a labelframe that had a dark background, and instead of a border I wanted an underline under the label. Something like this:
Common tasks ------------------------------ * task one * task two * task three
The initial stumbling blocks were how to replace the border with a single line, and how to get the background of the label to change. The following code is what I came up with.
The solutions to the two stumbling blocks turned out to be pretty trivial. For the former I had to modify the layout of my frame to use a separator element rather than a border element. For the latter, the solution was to realize I had to configure the background of "custom.TLabelframe.Label" rather than just "custom.TLabelframe".
Here's the code, which should be full cut'n'pasteable:
package require Tk
font create underlineFont {*}[font actual TkDefaultFont] -underline true
set background #0b223a
set foreground white
ttk::style configure custom.TLabelframe.Label \
-background $background \
-foreground $foreground
ttk::style configure custom.TLabelframe \
-background $background \
-foreground $foreground \
-labeloutside true \
-labelmargins {0 0 0 4}
ttk::style layout custom.TLabelframe {
Separator.separator -sticky new
}
ttk::style configure custom.TButton \
-background $background \
-foreground $foreground \
-anchor w
ttk::style map custom.TButton \
-font {active underlineFont}
ttk::style layout custom.TButton {
border -children {
padding -sticky nswe -border 1 -children {
label -sticky nswe
}
}
}
. configure -background $background
ttk::labelframe .lf -style custom.TLabelframe -text "Common Tasks"
# N.B. \u2022 is a unicode bullet
ttk::button .lf.b1 -style custom.TButton -text "\u2022 task one"
ttk::button .lf.b2 -style custom.TButton -text "\u2022 task two"
ttk::button .lf.b3 -style custom.TButton -text "\u2022 task three"
pack .lf.b1 .lf.b2 .lf.b3 -side top -fill x -anchor w
pack .lf -side top -fill both -expand true -padx 4 -pady 4jnc Feb 15, 2010: labelframe has the cool option of -labelwidget. This enables common frames with a checkbox to enable/disable the frames contents. An example:
package require Tk
set ::enabled 0
set ::name World
ttk::labelframe .lf1
ttk::checkbutton .lf1.cb1 -text "Say Hello To" -variable ::enabled -command {
if {$::enabled} {
.lf1.e1 configure -state normal
.b1 configure -state normal
} else {
.lf1.e1 configure -state disabled
.b1 configure -state disabled
}
}
.lf1 configure -labelwidget .lf1.cb1
ttk::entry .lf1.e1 -state disabled -textvariable ::name -state disabled
pack .lf1.e1 -fill x
ttk::button .b1 -text {Say Hello} -command { puts "Hello, $::name" } -state disabled
ttk::button .b2 -text Exit -command exit
pack .lf1 .b1 .b2 -fill x -expand yes
focus -force .b1See the page frame for a descriptions and solutions.