Hello ltk-users
After looking at gtk, qt, and other widget tool kits, from my noob perspective, ltk-tile looked the most promising (even I might be able to do it!) for creating guis with native look and feel. Hats off to Mr. Herth in extreme thanks for his work.
However, I am finding scanty documentation on ltk-tile, and have been mostly relying on the ltk-tile.lisp file to try and figure out it's syntax. , In the example function (tile-test), though creating a window with a label, an entry, and a button, the button doesn't do anything.
I am hereby pasting in the code of two separate files. The first one successfully uses ltk to create a frame with a button in it that outputs "Hello!" to the console when the button is clicked.
The second file tries to do the same thing, only using ltk-tile instead, but it is unsuccessful at outputing anything to the console. Because I am new to lisp, I still sometimes separate and indent the parentheses to help me visually comprehend what is inside of what.
Here is code of first file:
*;; making a button in ltk that outputs "Hello" to the console when clicked
; load dependent systems (load "/usr/local/lisp/systems/ltk/ltk") (in-package :ltk)
; define function (defun hellobutton () (with-ltk () (let* ( (f (make-instance 'frame)) (b (make-instance 'button :master f :text "hellobutton" :command (lambda () (format t "~%~THello!~%")))) ) (pack f) (pack b) (mainloop) )))
; use function (hellobutton) *
The above worked!!! But when I try it with ltk-tile it doesn't work. Here is the ltk-tile code that is trying to do same thing:
*;; trying to make a button with ltk-tile that outputs "Hello" to the console when clicked
; load dependent systems (load "/usr/local/lisp/systems/ltk/ltk") (load "/usr/local/lisp/systems/ltk/ltk-tile") (in-package :ltk-tile)
; define function (defun hellobutton () (activate-tile) (with-ltk () (let* ( (f (make-instance 'frame)) (b (make-instance 'button :master f :text "hellobutton" :command (lambda () (format t "~%~THello!~%")))) ) (pack f) (pack b) (dolist (theme (theme-names)) (make-menubutton mtheme theme (lambda() (use-theme theme)))) (mainloop) )))
; use function (hellobutton) *
Unfortunately I am new to lisp, tcl, tk, and gui programming in general. Any links to additional examples or tutorials on ltk-tile would be appreciated. I am happy to buy books too, so long as they cover ltk-tile.
Thanks in advance,
--Slac-in-the-box
(p.s. I've started my 12-year-old on lisp, and he has already made a text game in the fashioned after bsd-games "adventure" and he squeals with excitement (same joyous sounds he makes on the way to visit other kids) whenever he gets something to work! He is only a day or two behind on learning ltk and is asking questions for which I haven't any answers. Thus, the pressure is on for me to find answers!)
Hi Everett,
as it is late over here, only a very brief answer: in the meantime, ltk-tile has been merged into the main ltk library, if you grab the latest ltk version from: http://ltk.rplay.net/svn/branches/ltk/repl/ltk.lisp you get a ltk which uses the tile widget set by default (assuming you are running tcltk 8.5 or above). The ltktest program contained within ltk.lisp also contains some demo code to switch between the different tile styles on your system - just try running (ltk:ltktest). If you have any more questions, I will gladly answer them tomorrow :)
Peter
Wow: thanks for the wonderfully rapid response. Yes, the latest ltk made the issue I was having obsolete, now that tile is merged!
The weekend came, so I had a small window of time to try and put all the pieces of this ltk stuff together and make a small window that did something. In this case the widget computes the area of a circle, when given the diameter--rather elementary, but a start. Everytime I had a question, I ended up finding answers in the archives of this mailing list! Since it was my first try at making a gui that did something other than say "hello," and since I am new to lisp and new to programming in general, I am pasting this trivial excercise in hopes that you (or any advanced ltk-user) could offer criticism as to best practices, etc:
*;;;;; area.lisp endeavors to create a widget that calculates the area of a circle when given a diamter*
*;; load dependent systems (load "/usr/local/lisp/systems/ltk/ltk") (in-package :ltk)
;; define function (defun circularea () (with-ltk (:debug-tcl nil) (wm-title *tk* "circularea") (let* ( (label-d (make-instance 'label :text "A circle with a diameter of ")) (entry-d (make-instance 'entry :text "0")) (label-u (make-instance 'label :text "units")) (label-a (make-instance 'label :text "has an area of ")) (label-r (make-instance 'label :text "0")) (label-su (make-instance 'label :text "square units")) (b (make-instance 'button :text "calculate" :command (lambda () (progn (setf diameter (read-from-string (text entry-d))) (setf radius (/ diameter 2)) (setf pi 3.145927) (setf area (* pi (* radius radius))) (setf (text label-r) area) )))) ) (pack label-d) (pack entry-d) (pack label-u) (pack label-a) (pack label-r) (pack label-su) (pack b) )))
;; use function (circularea) *
Thanks again for making gui programming possible for the rest of us.
--Everett
On Thu, Apr 8, 2010 at 2:31 PM, Peter Herth herth@peter-herth.de wrote:
Hi Everett,
as it is late over here, only a very brief answer: in the meantime, ltk-tile has been merged into the main ltk library, if you grab the latest ltk version from: http://ltk.rplay.net/svn/branches/ltk/repl/ltk.lisp you get a ltk which uses the tile widget set by default (assuming you are running tcltk 8.5 or above). The ltktest program contained within ltk.lisp also contains some demo code to switch between the different tile styles on your system - just try running (ltk:ltktest). If you have any more questions, I will gladly answer them tomorrow :)
Peter
ltk-user site list ltk-user@common-lisp.net http://common-lisp.net/mailman/listinfo/ltk-user
Hi Everett,
I have to say, from the general style your code basically looks like the code I would write. Just a few comments, none of them ltk related:
- you set some variables, but never define them, rather use let* - what lisp are you using, SBCL has pi defined as a constant? - and the biggest one: DON'T use read on user input carelessly, try for example entering #.(do-msg "huch!") instead of a number and press calculate... read allows for evaluation of arbitrary lisp code.
Of course, the dialog layout could be different, but thats just fiddling a bit with the options of pack...
So the code could look like:
(defun circularea () (with-ltk (:debug-tcl nil) (wm-title *tk* "circularea") (let* ((label-d (make-instance 'label :text "A circle with a diameter of ")) (entry-d (make-instance 'entry :text "0")) (label-u (make-instance 'label :text "units")) (label-a (make-instance 'label :text "has an area of ")) (label-r (make-instance 'label :text "0")) (label-su (make-instance 'label :text "square units")) (b (make-instance 'button :text "calculate" :command (lambda () (let* ((diameter (let ((*read-eval* nil)) (read-from-string (text entry-d)))) (radius (/ diameter 2)) (area (* pi (* radius radius)))) (setf (text label-r) area)))))) (pack label-d) (pack entry-d) (pack label-u) (pack label-a) (pack label-r) (pack label-su) (pack b) )))
Peter
Howdy Peter
I have to say, from the general style your code basically looks like
the code I would write.
Makes sense, since it's your code that I'm copying, hehe.
- what lisp are you using, SBCL has pi defined as a constant?
I have both clisp 2.48 and sbcl 1.0.35 installed, and just discovered that clisp also has pi predefined. I started with clisp because it was already included with slackware, and the logic of a slacker is: if Pat thought it was good enough, then it must be. However, I have since learned that sbcl compiles to machine code whereas clisp compiles to byte code, and even in the ltk package, clisp can't do the "serve-event" stuff. My goal is to write code that does read-time conditionalization for clisp and sbcl, and to use clisp when working on non-profit projects and sbcl when working on commercial projects.
Thanks for this invaluable resource. I've been trying out the different widgets, and just tried the notebook instance, and am using it in my current endeavor of making a gui to help with the maintenance of my dns server (i'm tired of manually creating and editing zone files by hand)... hopefully everything will work and I won't be back here begging for deliverance from my confusion.
Thanks again,
--Everett
On Tue, Apr 13, 2010 at 1:43 PM, Peter Herth herth@peter-herth.de wrote:
Hi Everett,
I have to say, from the general style your code basically looks like the code I would write. Just a few comments, none of them ltk related:
- you set some variables, but never define them, rather use let*
- what lisp are you using, SBCL has pi defined as a constant?
- and the biggest one: DON'T use read on user input carelessly, try
for example entering #.(do-msg "huch!") instead of a number and press calculate... read allows for evaluation of arbitrary lisp code.
Of course, the dialog layout could be different, but thats just fiddling a bit with the options of pack...
So the code could look like:
(defun circularea () (with-ltk (:debug-tcl nil) (wm-title *tk* "circularea") (let* ((label-d (make-instance 'label :text "A circle with a diameter of ")) (entry-d (make-instance 'entry :text "0")) (label-u (make-instance 'label :text "units")) (label-a (make-instance 'label :text "has an area of ")) (label-r (make-instance 'label :text "0")) (label-su (make-instance 'label :text "square units")) (b (make-instance 'button :text "calculate" :command (lambda () (let* ((diameter (let ((*read-eval* nil)) (read-from-string (text entry-d)))) (radius (/ diameter 2)) (area (* pi (* radius radius)))) (setf (text label-r) area)))))) (pack label-d) (pack entry-d) (pack label-u) (pack label-a) (pack label-r) (pack label-su) (pack b) )))
Peter
ltk-user site list ltk-user@common-lisp.net http://common-lisp.net/mailman/listinfo/ltk-user