# label.tcl -- # Label selection. # You can double-click (Button 1) any label to set the selection to the # label's text. If a label can take focus (with the -takefocus option), # a single click (Button 1) will focus the label and then you can Cut, # Copy and Paste with <Control-x>, <Control-c> and <Control-v>. # Version : 0.0.1 # Author : Mark G. Saye # Email : [email protected] # Copyright : Copyright (C) 2003 # Date : February 20, 2003 # ====================================================================== namespace eval label {} package require Tk package provide label 0.0.1 # ====================================================================== proc label::button1 {W} { if { [string equal [$W cget -state] disabled] } { return } if { [$W cget -takefocus] } { focus $W } } # ====================================================================== proc label::copy {W} { clipboard clear clipboard append [$W cget -text] } # ====================================================================== proc label::cut {W} { copy $W if { ![string equal [$W cget -state] disabled] } { $W configure -text "" } } # ====================================================================== proc label::paste {W} { if { [catch {clipboard get -displayof $W} clip] } { puts stderr "\[$::errorCode\] $clip" return } if { ![string equal [$W cget -state] disabled] } { $W configure -text $clip } } # ====================================================================== proc label::focus:in {W} { } # ====================================================================== proc label::focus:out {W} { } # ====================================================================== proc label:handle {W offset maxChars} { return \ [string range [$W cget -text] $offset [expr {$offset+$maxChars-1}]] } # ====================================================================== proc label::normal {W} { # label has lost the selection - reset state to normal if { [string equal [$W cget -state] active] } { $W configure -state normal } } # ====================================================================== proc label::select {W} { if { [string equal [$W cget -state] disabled] } { return } $W configure -state active selection own -command [list label::normal $W] $W selection handle -type UTF8_STRING $W [list label:handle $W] selection handle $W [list label:handle $W] } # ====================================================================== bind Label <FocusIn> [list label::focus:in %W] bind Label <FocusOut> [list label::focus:out %W] bind Label <<Copy>> [list label::copy %W] bind Label <<Cut>> [list label::cut %W] bind Label <<Paste>> [list label::paste %W] bind Label <Double-1> [list label::select %W] bind Label <Button-1> [list label::button1 %W] bind Label <Control-x> [list event generate %W <<Cut>>] bind Label <Control-c> [list event generate %W <<Copy>>] bind Label <Control-v> [list event generate %W <<Paste>>] # ====================================================================== # demo code proc main {{argc 0} {argv {}}} { entry .e .e insert end "Entry - Hello World" label .l1 -text "Label Without Focus" label .l2 -text "Label With Focus" \ -takefocus 1 \ -highlightthickness 1 \ -relief sunken -bd 1 global state set state [.l2 cget -state] foreach _state {normal active disabled} { set r .$_state radiobutton $r \ -text $_state \ -variable state \ -value $_state \ -command [list .l2 configure -state $_state] } button .b -text Close -default active -command exit pack .b -side bottom -anchor se pack .e -side top -expand 0 -fill x -padx 20 -pady 20 pack .l1 -side top -expand 0 -fill x -padx 20 -pady 20 pack .l2 -side top -expand 0 -fill x -padx 20 -pady 20 pack .normal -side top -expand 0 -fill x pack .active -side top -expand 0 -fill x pack .disabled -side top -expand 0 -fill x } # ====================================================================== if { [info exists argv0] && [string equal [info script] $argv0] } { main $argc $argv } # ======================================================================
KBK A very pretty discussion of bindings and clipboard management. Nevertheless, most of us prefer an entry or text with -state disabled for implementing a UI component that supports selection but not modification.MGS - Agreed. But this way, you can load this on top of any existing code, without modification, to get the desired functionality. And you can use features of a label that an entry doesn't have (e.g. compound images). And labels do use (slightly) less memory then entry widgets. I also prefer labels if you want text wrapping. See label wrapping.Those interested in selection and clipboard differences might like to check out Primary Transfer vs. the Clipboard.
TV Isn't the memory question a bit overly concerned, I've used tcl/tk on a windows 3.1 machine with what is it 8 meg of main mem, and could easily run Bwise for instance. How much data is in a label or overseeable displayed text anyhow?MGS - Agreed, memory consumption is not really a concern, I was just listing the features in favour of labels vs entry and text widgets. I am also looking at Tcl/Tk for embedded/handheld use, so every little bit of efficiency can help.
MGS [2003/04/20] - I have combined the above code with that in label wrapping and created a package which you can find in the Links section at Mark G. Saye.
WJG (25/09/13) This is a standard feature of the gnocl::label widget, just set the -selectable option to '1'.
See also: