See Ttk, a part of Tk 8.5, for a core widget set that includes a separator. Its documentation can be found at http://www.tcl.tk/man/tcl8.5/TkCmd/ttk_separator.htm .
A separator can be rendered by a single frame suitably packed or grided:
proc separator {path} { return [frame $path -relief groove -borderwidth 2 -width 2 -height 2] } # Horizontal separator pack [separator .sep] -fill x2014-09-24: I find the following definitions work better and look nicer. And they're not too expensive (Ni!).(Nomenclature: to me, a horizontal separator is one that looks like a horizontal line but stacks vertically between other widgets.)
proc hseparator path { frame $path -relief flat -borderwidth 3 -height 0 -pady 0 pack [frame $path.inner -relief groove -borderwidth 2 -height 2 -pady 0] -expand yes -fill x set path } # grid it: grid [button .a -text abc] -sticky ew grid [hseparator .sep] -sticky ew grid [button .b -text def] -sticky ew # pack it: pack [button .a -text abc] pack [hseparator .sep] -fill x pack [button .b -text def]The result of gridding / packing isn't quite the same, since the gridded separator will stretch to the width of the other widgets, while a packed separator stretches to the width of the window.
proc vseparator {path} { frame $path -relief flat -borderwidth 3 -width 0 -padx 0 pack [frame $path.inner -relief groove -borderwidth 1 -width 0 -padx 0] -expand yes -fill both pack [label $path.inner.lbl -text {} -borderwidth 0 -width 0 -padx 0] set path } # grid it: grid [button .a -text abc] [vseparator .sep] [button .b -text def] -sticky w # pack it: pack [button .a -text abc] -side left pack [vseparator .sep] -side left -fill y pack [button .b -text def] -side leftHere, the result of gridding or packing is more or less the same, since the window will shrink to the height of the widgets.