Seesaw(Clojure)按钮点击无法获取下拉框新选中值问题
解决Seesaw按钮点击时函数提前执行的问题
这个问题我之前在Seesaw开发中也碰到过,根源在于Common Lisp的立即求值特性——你现在的代码写法会导致load-data在程序启动时就被执行,而不是等按钮点击时才触发。
问题分析
你写的这段代码:
(listen load-data-btn :action (load-data (selection year-cmb) (selection month-cmb) (selection day-cmb)))
在Lisp里,括号包裹的表达式会被立即求值。也就是说,当listen函数被调用的时候,(load-data ...)已经执行完毕了,它返回的结果被当成了:action的参数。所以程序一启动就获取了下拉框的初始选中值,之后无论怎么点击按钮,用的都是最开始的那个值。
解决方案
要解决这个问题,你需要把load-data的调用包装成一个匿名函数,这样只有当按钮被点击时,这个匿名函数才会被执行,此时才会去获取下拉框的当前选中值。修改后的代码如下:
(listen load-data-btn :action (lambda () (load-data (selection year-cmb) (selection month-cmb) (selection day-cmb))))
原理说明
这里的lambda () ...创建了一个无参的匿名函数。当按钮被点击时,Seesaw会自动调用这个匿名函数,这时才会执行(selection year-cmb)、(selection month-cmb)这些操作,拿到下拉框当前的选中值,再传递给load-data函数,这样就能正确获取用户新选择的日期了。
小提示
在Seesaw中,所有事件响应的动作(比如按钮点击、输入框变化),都应该传递一个函数(或匿名函数)作为:action的参数,而不是直接写函数调用表达式,否则都会出现这种提前求值的问题。
内容的提问来源于stack exchange,提问作者broliverparker
相关产品推荐
相关产品推荐

