[ltk-user] Button/Sender associated with Event?

Eric Hochmeister erichochmeister at gmail.com
Tue Feb 7 05:01:36 UTC 2006


Hi Peter,

Thanks for the detailed response.  This helps alot (especially that
explanation of radio buttons) and gives me everything I need.  I
didn't even think of using closures.. and this was a nice.. aha
moment.

Thanks!

Eric


On 2/5/06, Peter Herth <herth at peter-herth.de> wrote:
> Hi Eric,
>
> On 2/5/06, Eric Hochmeister <erichochmeister at gmail.com> wrote:
> > Hi,
> >
> > The functionality I'm looking for is that I want to set a button's
> > action to be a function.  When the function is called, I want to know
> > which button called it.  This is because many buttons can be linked to
> > the same function.  How do I accomplish this?
>
> I wonder why you need to know that and cannot know yet... usually, at
> the place where I define callbacks or event functions, the widget or
> the application which has a reference to the widget is in the lexical
> scope, so the callbacks can just close over it. So far, this was
> enough for all of my needs.
>
> > I looked at the docs for :command and it seems like they only pass
> > "values" to the function.  (what was changed, etc.)
> >
> > So I figured, maybe I need to look at binding, it seems to send out an
> > event.  So I tried it, and I noticed this...
> >
> > radio button value = NILl:(:EVENT "w13" 13 16 ?? ?? ?? ?? 273 324 1)<=
> > event = #S(LTK:EVENT :X 13 :Y 16 :KEYCODE ?? :CHAR ?? :WIDTH ??
> > :HEIGHT ?? :ROOT-X 273 :ROOT-Y 324 :MOUSE-BUTTON 1)
> >
> > The Tcl representation seems to have access to the widget that caused
> > the event ie. "w13" but the lisp representation doesn't.  I looked at
> > the structure for event and this indeed seems to be the case.
> >
> > (defstruct event
> >   x
> >   y
> >   keycode
> >   char
> >   width
> >   height
> >   root-x
> >   root-y
> >   mouse-button
> >   )
> >
> > So now I'm puzzled.
> >
> > Is there any way to accomplish the functionality I'm looking for??
> > (other than hacking up my own way with functions which emulate this?)
> > I must be missing something.
>
> We could consider putting the widget creating the event in the event
> structure, if that is needed. As you have seen correctly, the name of
> the widget is available, we would need to have a hashtable around to
> get the widget object from that name. But look at my radio-button
> example to see how I solve this usually.
>
> > Also, another side question.  I'm playing around with radio buttons
> > and I was trying to figure out how to get the state to be on or off..
> > and by state I mean whether the radio button is selected or not (ON or
> > OFF).  From what I can tell, if the :value of a radio button is nil,
> > then it's ON.  If it has any other value than nil then its OFF.  Is
> > this right??  Its just puzzling me cause it seems so unintuitive.
>
> Well, radio-buttons are not extremely elegant, but here is how you use them:
> When you create a radio-button, you pass 2 important arguments
> "variable" the name of the radio button group to build, and "value"
> the value the variable contains if the radio-button has been selected.
>  I modified ltktest to give a simple radio-button example:
>
>       (let* ((bar (make-instance 'frame))
>              (fradio (make-instance 'frame :master bar))
>              (leggs (make-instance 'label :master fradio :text "Eggs:"))
>              (r1 (make-instance 'radio-button :master fradio :text
> "fried" :value 1 :variable "eggs"))
>              (r2 (make-instance 'radio-button :master fradio :text
> "stirred" :value 2 :variable "eggs"))
>              (r3 (make-instance 'radio-button :master fradio :text
> "cooked" :value 3 :variable "eggs"))
>              (fr (make-instance 'frame :master bar))
>              (lr (make-instance 'label :master fr :text "Rotation:"))
>              (bstart (make-instance 'button :master fr :text "Start" :command
> 'start-rotation))
>              (bstop  (make-instance 'button :master fr :text "Stop"  :command
> 'stop-rotation))
>     .....
>
>         (pack bar :side :bottom)
>         (pack (list fradio leggs r1 r2 r3) :side :left)
>         (dolist (r (list r1 r2 r3))
>           (let ((button r))
>             (setf (command r) (lambda (val)
>                                 (declare (ignore val))
>                                 (eggs button)))))
>
> and finally the event handling fuction:
>
> (defun eggs (radio)
>   (format t "Prepare ~a eggs.~%"
>           (case (value radio)
>             (1 "fried")
>             (2 "stirred")
>             (3 "cooked")))
>   (finish-output))
>
> The variable argument can be an arbitrary string, as long as all the
> radio buttons in that group have the same one. Of course, I could just
> have passed value to the function eggs, but I wanted to demonstrate,
> how you get access to the widgets.
>
> Peter
> _______________________________________________
> ltk-user site list
> ltk-user at common-lisp.net
> http://common-lisp.net/mailman/listinfo/ltk-user
>



More information about the ltk-user mailing list