newlisp-tk Entry widget does not display textvariable

Q&A's, tips, howto's
jp
Posts: 22
Joined: Sun Mar 21, 2004 5:21 am

newlisp-tk Entry widget does not display textvariable

Post by jp »

I have been trying to mimic the passing of a tcl variable into the newlisp-tk entry widget but alas, regardless the way I am trying to bring the variable into the entry widget it fails.

============ test.tcl

set ok {Entry!}
wm title . $ok
entry .e -width 30 -textvariable ok
pack .e

=========== test.lsp

(define (test)
(tk "if {[winfo exists .test] == 1} {destroy .test}")
(tk "toplevel .test")
(set! ok (tk "set display {entry!}"))
(tk "wm title .test " ok)
(tk "entry .test.e -width 30 -textvariable " ok)
(tk "pack .test.e")
)

Here the variable is assigned to the tk widget title but fails to be acknowledged by the entry widget.
Needless to say I have tried all sorts of combinations which come to the mind; nothing seems to let newlisp-tk to give a pre-established variable to the entry widget. Could someone be so kind to cast some light on it!

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

Hello jp,
Welcome to the board.

Do not mix up variables in the TCL memory with the variables in newLISP.

Code: Select all

(define (test)
	(tk "if {[winfo exists .test] == 1} {destroy .test}")
	(tk "toplevel .test") 
	(tk "global display;set display {entry!}")
	(tk "global display;wm title .test $display")
	(tk "entry .test.e -width 30 -textvariable display")
	(tk "pack .test.e")
	)
Hans-Peter

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

You also could put everything in one string, limited by [text] ...[/text]

(define (test)
(tk
[text]
if {[winfo exists .test] == 1} {destroy .test};
toplevel .test;
global display;
set display {entry!};
wm title .test $display;
entry .test.e -width 30 -textvariable display;
pack .test.e;
[/text]
))

I think the important thing here to mention is, that the -textvariable wants a variable name, not the contents string. And ist seems to work only with a top level variable. Taking the 'global display' statement away, things don't work anymore. Everyting newLISP passes to TCL/TK will be executed not at top level, but inside a subroutine, this is why the 'global display' statement was necessary.

Lutz

jp
Posts: 22
Joined: Sun Mar 21, 2004 5:21 am

Post by jp »

Thanks a lot Hans-Peter and Lutz for the prompt replies

Actually, I was aware that –textvariable expected a variable name and I did make an attempt to declare display as global but as I could not chain it properly it did fail so I made a synoptic representation instead.
Perhaps a paragraph on the newlisp-tk documentation should be devoted on the proper chaining of commands for the interfacing between newlisp and tk.
Now with the overcoming of the hurdles interfacing the tk entry widget nothing stand in the way of a true interactivity between newlisp and tk.

Jean-Pierre

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

Thanks Jean-Pierre for the suggestion and welcome to the discussion forum.

The next version of the manual will expand on this a little bit more. What we really need is a comprehensive example with all the basic widgets in it, explaining and showing all the specifics when interacting between newLISP and Tcl/Tk. I hope one day I will get around doing it.

Lutz

jp
Posts: 22
Joined: Sun Mar 21, 2004 5:21 am

Post by jp »

I realise, if one finds the constant calling of the global variable inopportune, one can directly access the variable with the following...

(define (test)
(tk "if {[winfo exists .test] == 1} {destroy .test}")
(tk "toplevel .test")
(tk "variable display")
(tk "set display {entry!}")
(tk "wm title .test $::display")
(tk "entry .test.e -width 30 -textvariable display")
(tk "pack .test.e")
)

Jean-Pierre

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

It works for the title but then I still get "cant read ::display no such variable", I think there was some thing still in your Tcl/Tk namespace from before? Try it with a fresh start of newLISP-tk.

Lutz

jp
Posts: 22
Joined: Sun Mar 21, 2004 5:21 am

Post by jp »

Indeed you are right; under a new session newlisp fails to find the variable.

Jean-Pierre
Lutz wrote:It works for the title but then I still get "cant read ::display no such variable", I think there was some thing still in your Tcl/Tk namespace from before? Try it with a fresh start of newLISP-tk.

Lutz
But the following seems to work!

(define (test)
(tk "if {[winfo exists .test] == 1} {destroy .test}")
(tk "toplevel .test")
(tk "variable display")
(tk "set ::display {entry!}")
(tk "wm title .test $::display")
(tk "entry .test.e -width 30 -textvariable ::display")
(tk "pack .test.e")
)

Jean-Pierre

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

thanks Jean-Pierre, I will include this example in the manual, because the question about 'how to keep variable state' is asked frequently. It seems that the key is the 'variable varName' declaration and the reference to it with ::varName

Lutz

jp
Posts: 22
Joined: Sun Mar 21, 2004 5:21 am

Post by jp »

Actually, 'variable ::varName' declaration and the reference to it with ::varName

The advantage of having direct access to tcl variables is to let tk have as many variables as it is deemed necessary for the good conduct of tk widgets processes, but also that newlisp can always modify them at will!

Jean-Pierre
Lutz wrote:thanks Jean-Pierre, I will include this example in the manual, because the question about 'how to keep variable state' is asked frequently. It seems that the key is the 'variable varName' declaration and the reference to it with ::varName

Lutz

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

It seems that the variable declaration (variable ::display) is not necessary at all. The global namespace prefix :: seems to be enough, and 'set' then instoruces the variable:

(define (test)
(tk "if {[winfo exists .test] == 1} {destroy .test}")
(tk "toplevel .test")
(tk "set ::display {entry!}")
(tk "wm title .test $::display")
(tk "entry .test.e -width 30 -textvariable ::display")
(tk "pack .test.e")
)

Lutz
ps: see "Practical Programming in Tcl and Tk" by Brent B. Welch, p.198

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

>ps: see "Practical Programming in Tcl and Tk" by Brent B. Welch, p.198

This is correct for the third edition.

For the current fourth edition take a look at p.208.

;-)
Hans-Peter

newdep
Posts: 2038
Joined: Mon Feb 23, 2004 7:40 pm
Location: Netherlands

Post by newdep »

And in the Second Edition its neighter on 198 nor 208 but at 170 :-)
(if we're talking about the global namespace callbacks..)
-- (define? (Cornflakes))

jp
Posts: 22
Joined: Sun Mar 21, 2004 5:21 am

Post by jp »

> It seems that the variable declaration (variable ::display) is not necessary at all.

I guess, it will depend entirely under which context we want the tcl variables to operate on, my impression is from the standpoint of newlisp, (variable display) will always be sufficient.

Jean-Pierre

gerhard zintl
Posts: 5
Joined: Sat Feb 14, 2004 10:43 am

Transfer of Variable-contents from Tk to newLisp

Post by gerhard zintl »

(define (test)
(tk "if {[winfo exists .test] == 1} {destroy .test}")
(tk "toplevel .test")
(tk "set ::display {entry!}")
(tk "wm title .test $::display")
(tk "entry .test.e -width 30 -textvariable ::display")
(tk "pack .test.e")
)
I'm just starting to experiment with newLisp.
How could you send back the content of the entry in ::display to newLisp?
Thanks in advance.
Gerhard Zintl

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

You could do the following:

(tk "set ::display")


or any other Tcl/Tk statement which would return the contents of the variable. This would return the contents of the entry widget in a string.

Read the chapter about "Writing applications with newLISP and Tcl/Tk" in the manual.

Lutz

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

>How could you send back the content of the entry in ::display to newLisp?

I think he means how to push it back from the GUI to newLISP.
The we must bind an TK event (for eample return key in entry widget) to a proc, where we call a function in newLISP.

A look into newLISP-tk.tcl from the source may be usefull.
Hans-Peter

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

the demo examples shipped with the Windows version also show how to bind events to buttons, mouse etc.

Lutz

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

here is a comprehensive example for an entry widget:

Code: Select all

(define (entry )
  (tk "if {[winfo exists .entry] == 1} {destroy .entry}")
  (tk "toplevel .entry")
  (tk "wm title .entry {entry example}")
  (tk "entry .entry.e -width 30 -textvariable ::display")
  (tk "bind .entry.e <Return> { Newlisp {(silent (get-entry-text))} }")
  (tk "pack .entry.e"))

(define (get-entry-text )
  (println (tk "set ::display")))
Whenever you hit the return/enter key you will see the contents of the entry widget displayed in the console. There are many other events you can bind to Tcl/Tk widget, get a book, i.e.: "Practical Programming in Tcl and Tk" by Brent Welch.

Lutz

gerhard zintl
Posts: 5
Joined: Sat Feb 14, 2004 10:43 am

comprehensive example for an entry widget:

Post by gerhard zintl »

Hallo Lutz,
I tested your 'entry example' and it runs like a charm.
Thank you very much for your prompt help.
I have some experience with Tcl/Tk and also Brent Welch's book fourth ed.
My problem was the data transfer connection between TK and newLISP
Gerhard Zintl

jp
Posts: 22
Joined: Sun Mar 21, 2004 5:21 am

Post by jp »

listbox widget example
Last edited by jp on Sat Mar 27, 2004 11:11 am, edited 1 time in total.

jp
Posts: 22
Joined: Sun Mar 21, 2004 5:21 am

Post by jp »

Lutz gave a comprehensive entry widget example.
Here is listbox widget example.
It is a file chooser, where one has simply to click a given file to either open or run it. One can easily extend it to make newlisp to distinguish directories and files and navigate drives and make newlisp to do all sorts of what not!
I choose to use start.exe from win98 instead of the internal command assoc since that command exists only on Win2k and WinXP.

Jean-Pierre

------------------------- fc.lsp

(define (listbox)
(tk
[text]
if {[winfo exists .fc] == 1} {destroy .fc}
toplevel .fc
set ::result ""
wm title .fc {File Chooser}
frame .fc.fr -borderwidth 10
pack .fc.fr -side top -expand yes -fill y

scrollbar .fc.fr.yscroll -orient vertical -command ".fc.fr.list yview"
scrollbar .fc.fr.xscroll -orient horizontal -command ".fc.fr.list xview"
listbox .fc.fr.list -width 20 -height 10 -setgrid 1 -yscroll ".fc.fr.yscroll set" -xscroll ".fc.fr.xscroll set"

button .fc.b -text {Exit All} -command exit
label .fc.lb -textvariable ::result
pack .fc.lb .fc.b -side top -fill x

grid .fc.fr.list -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid .fc.fr.yscroll -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
grid .fc.fr.xscroll -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid rowconfig .fc.fr 0 -weight 1 -minsize 0
grid columnconfig .fc.fr 0 -weight 1 -minsize 0

foreach i [lsort [glob *]] {
.fc.fr.list insert end $i
}

proc fiche {} {
set entry [open tmp w]
puts $entry $::result
close $entry
}

bind .fc.fr.list <ButtonRelease-1> {
set ::result [selection get]
set ext [string tolower [file extension $::result]]
switch -glob -- $ext {
"" { exec notepad $::result & }
".bat" { exec notepad $::result & }
".ini" { exec notepad $::result & }
".sys" { exec notepad $::result & }
".lsp" { fiche ; Newlisp {(entry)} }
default { exec c:/dos/start $::result & }
}
}
[/text]
))

(define (entry)
(eval (append '(load) (parse (read-file "tmp"))))
(delete-file "tmp"))

--------------------- end of code

jp
Posts: 22
Joined: Sun Mar 21, 2004 5:21 am

Post by jp »

Easier and little bit faster

Jean-Pierre

--------------------------- fx.lsp

(define (fx)
(tk
[text]
if {[winfo exists .fx] == 1} {destroy .fx}
toplevel .fx
wm title .fx {File Chooser}
frame .fx.fr -borderwidth 10
pack .fx.fr -side top -expand yes -fill y

scrollbar .fx.fr.yscroll -orient vertical -command ".fx.fr.list yview"
scrollbar .fx.fr.xscroll -orient horizontal -command ".fx.fr.list xview"
listbox .fx.fr.list -width 20 -height 10 -setgrid 1 -yscroll ".fx.fr.yscroll set" -xscroll ".fx.fr.xscroll set"

button .fx.b -text {Exit All} -command exit
label .fx.lb -textvariable ::result
pack .fx.lb .fx.b -side top -fill x

grid .fx.fr.list -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid .fx.fr.yscroll -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news
grid .fx.fr.xscroll -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news
grid rowconfig .fx.fr 0 -weight 1 -minsize 0
grid columnconfig .fx.fr 0 -weight 1 -minsize 0

foreach i [lsort [glob *]] {
.fx.fr.list insert end $i
}

bind .fx.fr.list <ButtonRelease-1> {
set ::result [selection get]
set ext [string tolower [file extension $::result]]
switch -glob -- $ext {
"" { exec notepad $::result & }
".bat" { exec notepad $::result & }
".ini" { exec notepad $::result & }
".sys" { exec notepad $::result & }
".lsp" { Newlisp {(entry)} }
default { exec c:/dos/start $::result & }
}
}
[/text]
))

(define (entry) (eval (append '(load) (list (tk "set ::result")))))

-------------------- end of code

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

Thanks for the comprehensive listbox example, a nice piece showing how to use the grid manager in Tk organizing several widgets.

Note that Tcl/Tk also has some built-in dialogs already, some of them for files too, try these:

(tk "tk_chooseColor")
(tk "tk_messageBox -message {Hello World!}")
(tk "tk_getOpenFile")
(tk "tk_getSaveFile")

All of these have many options but work in their minimalistic form shown here with useful return values.

Lutz

jp
Posts: 22
Joined: Sun Mar 21, 2004 5:21 am

Post by jp »

Thanks Lutz

Perhaps all the outstanding features of the newlisp tk interface should be mentioned in the newlip-tk documentation to ease the interfacing and to prevent the inadvertent 'reinventing of the wheel'.

Jean-Pierre

Locked