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 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.
-----------------
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.
Ok, thats all for now.
Thanks!
Eric
Hi Eric,
On 2/5/06, Eric Hochmeister erichochmeister@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
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@peter-herth.de wrote:
Hi Eric,
On 2/5/06, Eric Hochmeister erichochmeister@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@common-lisp.net http://common-lisp.net/mailman/listinfo/ltk-user