TK
Frame, Text, Scrollbar, Scale
Button, Entry, Label
Widgets 1 : Button, Entry, Label
Three things need to be said about widgets. First is the path. This I have explained earlier. The paths of all widgets must be unique and will be used when ever that widget needs to be accessed. Second is the options. Each widget has some options which can be used to configure it. This is usually done when the widget is declared, but it can be done afterward also. The final thing is commands. Each widget has some commands which also can be used to configure it or make it do some thing.
But before we begin, we need to know a little about the pack command. I have explained this earlier but just doing it one more time so that you don't have to push the back button. Pack is a geometry manager. Another geometry manager is 'grid' and I like it better - we will explore that latter. Pack is much more simpler than grid.
The line pack .hello tells the interpreter to pack the widget called ".hello".
If the command was pack .hello -in .frame, the widget .hello will be packed in another widget called .frame. In the absence of the '-in' option, the specified widget is put in the main window.
button
This will make a button. It can be configured to execute some code when pushed. This will usually refer to a function so when the button is pushed, the function will run. An button is shown using HTML below.
| -text "TEXT" | TEXT will be the text displayed on the button |
| -command "CODE" | CODE will be the code that is executed when the button is pushed |
proc push_button {} {
... whatever ...
}
button .but -text "Push Me" -command "push_button"
pack .but
entry
An entry is a widget that displays a one-line text string and allows the user to input and edit text in it. When an entry has the input focus it displays an insertion cursor to indicate where new characters will be inserted. An entry element is shown using HTML.
| -width NUMBER | Width of the input field. NUMBER should be an integer. |
| -textvariable VARIABLE | The contents of the variable VARIABLE will be displayed in the widget. If the text in the widget is edited, the variable will be edited automatically. VARIABLE should be given without a preceding '$' sign. |
| -state STATE | The state of the input field. It can be normal, disabled, or readonly. If it is readonly the text can't be edited. |
| Syntax | Description | Example |
| path get | The text inside input field can be taken by this command | set name [.ent get] |
| path delete FIRST ?LAST? | Delete one or more elements of the entry. FIRST is the index of the first character to delete, and LAST is the index of the character just after the last one to delete. If last isn't specified it defaults to FIRST+1, i.e. a single character is deleted. This command returns an empty string. | .ent delete 0 end |
| path insert index STRING | Insert the characters of STRING just before the character indicated by index. Index is 0 for the first character. The word "end" can be used for the last character | .ent insert end "Hello" |
Example
proc push_button {} {
.ent insert end "Hello"
}
entry .ent
button .but -text "Push Me" -command "push_button"
pack .ent
pack .but
label
This widget display text messages.
Example
proc push_button {} {
.ent insert 0 "Hello "
}
label .lab -text "Enter name:"
entry .ent
button .but -text "Push Me" -command "push_button"
pack .lab
pack .ent
pack .but

Comments
I came across a problem here though; I saved the first script as a file with the name "button.tcl" and tried to execute it using "wish button.tcl".
When I moved the mouse onto the form I got the following error:
---
unknown option "-state"
unknown option "-state"
while executing
"$w cget -state"
(procedure "tk::ButtonEnter" line 3)
invoked from within
"tk::ButtonEnter ."
(command bound to event)
---
It turns out the problem was the filename - renaming the file to btn.tcl solved the problem. Apparently button is a reserved word and naming a file using a reserved word can cause this error. I mention it here so that others who are as confused as I was might find it.
Thanks again for a very nice tutorial.
Derek
It is clearer to keep the response proc same, and only change the action within the proc, depending on some state variable. Such code is easier to read: one button -- one response proc. Otherwise, you get additional dependencies, things changing magically, etc. The clearer the structure of your program the better.
So, my suggestion would be to write your code this way:
proc push_button {} {
variable state
if { $state(button_action) eq "DO_SOMETHING" } {
DoSomething
} else {
DoSomethingElse
}
}
button .but -text "Push Me" -command "push_button"
1. Delete the contents and then insert the new text.
2. Assign the new value to the variable configured with -textvariable directly by set.
.ent delete 0 end
before the
.ent insert 0 "Hello"
and also .. if we have 2 sets of radio buttons for eg: sex male and female
and city delhi or NCR... how can we let the user select one from each category...
I tried but if i clik on male and then click on delhi .. the male radio button gets de selected...
I want colored text, and I'm sure there's a way somehow.
proc push_button1 {} {
exec xeyes &
}
proc push_button2 {} {
exec xcalc &
}
proc push_button3 {} {
exec xterm &
}
button .but1 -text "X eyes" -command "push_button1"
button .but2 -text "calculator" -command "push_button2"
button .but3 -text "terminal" -command "push_button3"
pack .but1
pack .but2
pack .but3
****************************************
set debug_string "......"
label .txt_debug -textvariable debug_string
button .but -text "Push Me" -command "cmd"
pack .txt_debug
pack .but
proc cmd { } {
set sAstr1 "abcd"
set sAstr2 "efgh"
global debug_string
set debug_string $sAstr1
# wait 2000 milliseconds
set EndWait [expr [clock clicks -milliseconds] + 2000]
while { [clock clicks -milliseconds] < $EndWait } {
}
set debug_string $sAstr2
}
****************************************
My question is that is there a way to get the patch of a widget? Because now I want to display the directory that I select in the entry left to the according browse button, but I couldn't find ways to know which of the browse button i've pressed after adding a few. Here's my code.
Thanks
#global variables
set current_row 2;
set current_entry "entry_";
list entry_list; #a list that contains the path oc each entry
list browse_button_list; #a list that contains the path of each browse button
list input_list;
frame .main
button .add_button -text "Add entry" -command "add_entry";
button .remove_button -text "Remove entry" -command "remove_entry";
entry .entry_1
button .browse_1 -text "Browse..." -command "browse";
lappend entry_list ".entry_1";
lappend browse_button_list ".browse_1";
grid .add_button -in .main -row 1 -column 1;
grid .remove_button -in .main -row 1 -column 2;
grid .entry_1 -in .main -row 2 -column 1;
grid .browse_1 -in .main -row 2 -column 2;
pack .main
proc add_entry {} {
global current_row browse_button_list entry_list;
set temp1 ".entry_";
set temp2 ".browse_";
append temp1 $current_row;
append temp2 $current_row;
entry $temp1
button $temp2 -text "Browse..." -command "browse";
grid $temp1 -in .main -row [expr {$current_row + 1}] -column 1;
grid $temp2 -in .main -row [expr {$current_row + 1}] -column 2;
lappend entry_list $temp1;
lappend browse_button_list $temp2;
incr current_row;
}
proc remove_entry {} {
global current_row browse_button_list entry_list;
set current_row [expr {$current_row-1}];
destroy [lindex $entry_list [expr {$current_row-1}]];
destroy [lindex $browse_button_list [expr {$current_row-1}] ];
set browse_button_list [lrange $browse_button_list 0 end-1]
set entry_list [lrange $entry_list 0 end-1]
}
proc browse {} {
variable state
global input_list;
lappend input_list [tk_chooseDirectory -initialdir D:/]
}
a, strong, em, b, i, code, pre, pandbrallowed. Other tags will be shown as code(< will become <). Urls, Line breaks will be auto-formated.