''[MGS]'' - Sometimes I want to be able to select the text in a label to paste into another application. So I wrote this little package to do just that. It wasn't as straightforward as I thought it might be, but at least I learned a few things about selection and the clipboard :-) # 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 , and . # Version : 0.0.1 # Author : Mark G. Saye # Email : markgsaye@yahoo.com # 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 [list label::focus:in %W] bind Label [list label::focus:out %W] bind Label <> [list label::copy %W] bind Label <> [list label::cut %W] bind Label <> [list label::paste %W] bind Label [list label::select %W] bind Label [list label::button1 %W] bind Label [list event generate %W <>] bind Label [list event generate %W <>] bind Label [list event generate %W <>] # ====================================================================== # 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 at: [http://www.speakeasy.org/~msaye/tk/label/] . ---- See also: * [selection] * [selection clear] * [selection handle] * [selection own] * [listbox selection] ---- [Category Package]