Discussion:
[Tkinter-discuss] more control over truncating long strings in Labels?
Russell E. Owen
2005-04-28 01:37:17 UTC
Permalink
I'd was wondering if there was some fairly easy way to display text in a
Label such that it is is anchored on the west (short strings are against
the left edge), but too-long strings are truncated on the left. This
would be useful for displaying very long path names. It might be even
nicer to truncate the text in the middle, replacing the excess text with
..., but truncating on the left would be fine.

I fear the only way is to use font metrics (using a tkFont object from
the tkFont module) and iteratively try to figure out what length of
string will fit. If so, it sounds messy. Hope I'm missing something.

-- Russell
Michael Lange
2005-04-28 03:33:02 UTC
Permalink
On Wed, 27 Apr 2005 11:33:49 -0700
Post by Russell E. Owen
I'd was wondering if there was some fairly easy way to display text in a
Label such that it is is anchored on the west (short strings are against
the left edge), but too-long strings are truncated on the left. This
would be useful for displaying very long path names. It might be even
nicer to truncate the text in the middle, replacing the excess text with
..., but truncating on the left would be fine.
I fear the only way is to use font metrics (using a tkFont object from
the tkFont module) and iteratively try to figure out what length of
string will fit. If so, it sounds messy. Hope I'm missing something.
-- Russell
I've done something like that by simply checking the length of the string, like this:

label = Label(parent, width=40, anchor='w')
if len(labeltext) > 36:
labeltext = '...%s' % labeltext[-33:]
label.configure(text=labeltext)

Maybe it's not perfect, but for me it worked fine.

Best regards

Michael
Jeff Epler
2005-04-28 04:05:41 UTC
Permalink
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
Jeff Epler
2005-04-29 19:22:07 UTC
Permalink
Post by Jeff Epler
This code is not well tested, but I'll share it anyway.
[snipped]

Someone asked me off-list if there was a reason I wrote this code in
tcl, not Python. No, there was no efficiency reason. I wrote this code
first for a tcl/tk app, then wrapped it for use from Python.

Jeff
-------------- 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/20050429/bf41dc79/attachment.pgp
Continue reading on narkive:
Loading...