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 4
jnc 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 .b1
See the page frame for a descriptions and solutions.