Text Widget Example

There have been several posts recently on clt, concerning the use of the text widget. Since I couldn't readily find the links to the existing examples that I have seen before, well here goes:


package require Tk 8
menu .menubar -type menubar
.menubar add cascade -label File -menu .menubar.file -underline 0

#file menu
menu .menubar.file -tearoff 0
.menubar.file add command -label "New" -underline 0 \
    -command { new } 
.menubar.file add command -label "Open..." -underline 0 \
    -command {
        set fileid [open $filename r]
         # filename is set in file_save_as
        set data [read $fileid $filesize]
        close $fileid
        .text.t insert end $data
        wm title . $filename
    }

proc save { } {
    set data [.text.t get 1.0 {end -1c}]
    set fileid [open $filename w]
    puts -nonewline $fileid $data
    close $fileid
}

proc file_save_as { } {
    global filename
    set data [.text.t get 1.0 {end -1c}]
    set file_types {
     {"Tcl Files" { .tcl .TCL .tk .TK} }
     {"Text Files" { .txt .TXT} }
     {"All Files" * }
    }

    set filename [tk_getSaveFile -filetypes $file_types\
        -initialdir pwd -initialfile $filename\
        -defaultextension .tcl]
    wm title . $filename
    set fileid [open $filename w]
    puts -nonewline $fileid $data
    close $fileid
}

tk appname "Edit"

I know this could have been even more minimalist, but thought this would answer most of the recent questions I have seen. Left one little glitch in here on purpose... Also, no error handling.

Hope this is helpful to someone. I remember (not too long ago), how long it took me to get this far working out of a book :^) so


Also, please note that the menu in the above script requires tcl/tk 8.0 or higher. There are some grab problems with this type of a menu when running Gnome.


A really minimal example is of course this one-liner:

if 0 {
    pack [text .t -wrap word] -fill both -expand 1
}

Even though it doesn't have a scrollbar, you can scroll with middle mouse-button held down. And you can paste into it, copy from it... all from one line of Tk code :^) RS


escargo 19 Apr 2005 - Somewhere along the way this file stopped being complete. When I used wish-reaper to download it, several important parts were missing. I had to go back to the revision history to reconstruct the new and file_get procs. I also had to reconstruct most of the menus.

EKB 19 April 2005 -- It still seems incomplete (??) Is it possible to restore it?

escargo - I would prefer to have it restored in place instead of having correcting code added after, since I want to use wish-reaper (or equivalent functions) to extract the code. (That's why I also put if 0 { in front of the minimal example above.)


EKB 19 April 2005 - Here's an alternative for the "File|Open..." menu command

First, make the File|Open command call a named proc:

.menubar.file add command -label "Open..." -underline 0 \
    -command file_open

This is usually a good idea, because then it is easy to bind it to a key combination, similar to using actions:

bind . <Control-o> file_open

The Ctrl-O key combination can now be added as an annotation on the menu, using the -accelerator switch:

.menubar.file add command -label "Open..." -underline 0 \
    -command file_open -accelerator "Ctrl+O"

The proc itself has some extra bells and whistles compared to the one above

proc file_open {} {
     global filename
     set data [.text.t get 1.0 {end -1c}]
     set file_types {
         { {Tcl Files} { .tcl .TCL .tk .TK} }
         { {Text Files} { .txt .TXT} }
         { {All Files} * }
     }

     set new_filename [tk_getOpenFile -filetypes $file_types\
         -initialdir [file dirname $filename] \
         -initialfile [file tail $filename] \
         -defaultextension .tcl]
     if {$new_filename == ""} {
         # The user pressed "cancel"
         return
     }
     if [catch {open $new_filename r} fileid] {
         # Error opening file -- with "catch", fileid holds error message
         tk_messageBox -icon error -message "Couldn't open \"$filename\":\n$fileid"
         return
     }
     # OK, didn't cancel, and filename is valid -- save it
     set filename $new_filename
     # ?? This was original: "set data [read $fileid $filesize]" -- where is
     #   variable "filesize" defined?
     set data [read $fileid]
     close $fileid
     # First, clear out text widget
     .text.t delete 1.0 end
     # Now, insert new file
     .text.t insert end $data
     wm title . $filename
}