[Tkinter-discuss] more control over truncating long strings in Labels?

Jeff Epler jepler at unpythonic.net
Wed Apr 27 23:05:31 CEST 2005


This code is not well tested, but I'll share it anyway.

You must create the label widget, and a variable to hold the string.
Then you call make_ellip with the widget, the variable, and the
side---"left", "right", or "center".  "left" gives abbreviated text like
"And no...", and so forth.

On at least some platform/fonts combinations, you can replace the "..."s
in the tcl_code with \N{HORIZONTAL ELLIPSIS} to get a true ellipsis
character.

#------------------------------------------------------------------------
# This code is in the public domain
tcl_code = u"""
proc ellip {text font avail {side l}} {
    set m [font measure $font $text]
    if {$m <= $avail} { return $text }
    for {set i [string length $text]} {$i >= 0} {incr i -1} {
        switch $side {
            l - le - lef - left {
                set s [string range $text 0 $i]...
            }
            r - ri - rig - righ - right {
                set j [expr [string length $text]-$i]
                set s ...[string range $text $j end]
            }
            c - ce - cen - cent - cente - center {
                set p [expr $i/2]
                set q [expr [string length $text]-$i+$p]
                set s [string range $text 0 $p]...[string range $text $q end]
            }
        }
        if {[font measure $font $s] <= $avail} { break }
    }
    set s
}

proc do_ellip { w args } {
    if {![winfo exists $w]} { return }
    upvar \#0 [bind $w <<EllipVariable>>] var
    set side [bind $w <<EllipSide>>]
    $w configure -text [ellip $var [$w cget -font] [winfo width $w] $side]
}

proc make_ellip {w v {side l}} {
    upvar \#0 $v var
    trace variable  var w [list do_ellip $w]
    bind $w <<EllipVariable>> $v
    bind $w <<EllipSide>> $side
    bind $w <Configure> {+do_ellip %W }
    bind $w <Destroy> [list +trace vdelete $v]
}
"""

def make_ellip(widget, variable, side="l"):
    call = widget.tk.call
    if not call("info", "commands", "make_ellip"):
        call("eval", tcl_code)
    return call("make_ellip", widget, variable, side)

def test():
    import Tkinter
    t = Tkinter.Tk()
    s = Tkinter.StringVar(t)
    s.set("And now for something completely different!")
    for side in "lcr":
        l = Tkinter.Label(t, width=5)
        make_ellip(l, s, side)
        l.pack(side="top", fill="x")
    t.mainloop()

if __name__ == '__main__': test()
#------------------------------------------------------------------------
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://mail.python.org/pipermail/tkinter-discuss/attachments/20050427/9c06372e/attachment.pgp


More information about the Tkinter-discuss mailing list