Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

tk entry usage

Status
Not open for further replies.

charlie007

Programmer
Jul 14, 2004
8
US
I am just statrting to learn tk. I have some experience with tcl on linux and now I am working on winxp.

All I want to do is enter some text and have it echoed back with tk_messageBox. The problem: the entry box appears, but does not wait for me to enter any text. Do I need a bind to synchronize or -vcmd?

pack [entry .e -textvar e -width 50]
tk_messageBox -message "$e" -type okcancel -icon question
 
You could use tkwait ...

pack [entry .e -textvar e -width 50]
tkwait variable e
tk_messageBox -message "$e" -type okcancel -icon question

this prevents the message box opening until the variable e is modified
 
Thanks sh00der. Before I saw your post I had figured out the tkwait but a little different than your example.

Here's the code now and a couple of questions.
__________________________________________
# set max length
set length 2
# validation proc
proc vcmd {length d s S} {
# check operation
if {$d != 1} { return 1; # not an insert operation }
# check length
if {[string length $s] == $length} { return 0; # overflow }
# check inserted chars
if {[string match {[A-z0-9.]} $S]} { return 1 }
# bad char
return 0
}

set w .entry1
catch {destroy $w}
toplevel $w
wm title $w "Entry Demonstration"
wm iconname $w "entry1"
frame $w.buttons
pack $w.buttons -side bottom -fill x -pady 2m
button $w.buttons.enter -text Enter -command "destroy $w"
pack $w.buttons.enter -side left -expand 1
pack [entry $w.e -validate key -textvar e -width 2 -vcmd [list vcmd $length %d %s %S] ]
tkwait visibility $w.e
focus $w.e
tkwait window $w

tk_messageBox -message $e -type okcancel -icon question

exit
________________________

Q:
1. I had to add a button because I could not figure out how to close the entry window otherwise. I want to have the user enter 2 characters and then hit the Enter key without using the mouse. Is there a way to made the Enter button the default so that when Enter key is pressed it continues?

2. In addition to the entry window another window opens first automatically and I don't necessarily want that. Is there a way to get rid of it?
 
1. you need to "bind" the enter key to the entry:
bind .entry1.e <Return> {<your command on "enter">}

2. you can't get rid of the first window but you don't need the second. Don't use "toplevel". The first window's name is ".".

Bob Rashkin
rrashkin@csc.com
 
Thanks Bong. Everything was working ok until I commented the tk_messageBox. Now the 2nd time and subsequent times that the entry window is opened there is no focus and the box. This sits in an endless loop sending some data to the com port. How do I get the focus on the entry window?

set dlen -1
# set max length
set length 2
set lensm1 [expr $length - 1]

# validation proc
proc vcmd {length d s S} {
set ::dlen $s
# check operation
if {$d != 1} { return 1; # not an insert operation }
# check length
if {[string length $s] == $length} { return 0; # overflow }
# check inserted chars
if {[string match {[0-8]} $S]} {
if {[string length $s] == $::lensm1} { focus $::w.buttons.enter }
return 1
}
# bad char
return 0
}
proc enter_button {} {
if {[string length $::dlen] != $::lensm1} {
focus $::w.e
} else {
destroy $::w
}
}
set input [open "com1" "r+"]

while { 1 } {
set w .entry1
catch {destroy $w}
toplevel $w
wm title $w "Entry Demonstration"
wm iconname $w "entry1"
frame $w.buttons
pack $w.buttons -side bottom -fill x -pady 2m
button $w.buttons.enter -text Enter -command "enter_button"
pack $w.buttons.enter -side left -expand 1
bind $w.buttons.enter <Return> {destroy $w}

pack [entry $w.e -validate key -textvar e -width 2 -vcmd [list vcmd $length %d %s %S] ]
tkwait visibility $w.e
focus $w.e
tkwait window $w
if { $e != "" } {
puts $input "[string range $e 0 0]*[string range $e 1 1]!"
flush $input
# tk_messageBox -message "[string range $e 0 0]*[string range $e 1 1]!" -type okcancel -icon question
}
set e ""
}
close $input
exit
 
I got around the problem by changing
focus $w.e
to
focus -force $w.e

Don't know why that worked, is it the proper way to fix?
 
I don't understand what happened but your solution seems pretty simple.

Bob Rashkin
rrashkin@csc.com
 
Is there any way to use the root window in a looping fashion like my app is doing witha secondary window? I can't even get past the tkwait because tkwait is waiting for the destroy of the window and once I do that the app is also destroyed.
 
Usually in Tk, a "window" can also be a frame. So, you don't need to wait on "." but on a frame within ".", say ".1.1" Then you can destroy the frame (destroy .1.1) and leave the window (and thus the app).

Bob Rashkin
rrashkin@csc.com
 
Would you give me an example of creating an entry and a button in the "." window? Whatever I tried is not working.
 
I use the packer geometry almost all the time. In order to keep everything straight, I usually build a grid of frames:
Code:
	for {set i 1} {$i<=3} {incr i} {
		pack [frame .$i -borderwidth 2 -relief groove] -side top
		for {set j 1} {$j<=$n} {incr j} {
			pack [frame .$i.$j -borderwidth 4] -side left
		}
	}
in this case 3x3. The frames are now .1.1, .1.2, ...

Since I like to label my entries, I'll use frame .1.1 for labels, .1.2 for entries, and .1.3 for buttons:
Code:
pack [label .1.1.L1 -text "first entry ->"] -side top
pack [entry .1.2.E1 -textvariable var1] -side top
pack [button .1.3.B1 -text Button1 -command {newProc $var1}] -side top

Bob Rashkin
rrashkin@csc.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top