Common lisp 如何使用ltk等待事件结束从函数返回?

Common lisp 如何使用ltk等待事件结束从函数返回?,common-lisp,ltk,Common Lisp,Ltk,我正在使用ltk为CommonLisp中的Dijkstra算法开发一个GUI应用程序。但是,要将节点放置在画布上,我需要它的标签,要这样做,执行必须等到用户输入字符串(并按Return键)以使用此值启动节点实例。在没有监听过程的情况下,返回发生在创建第二个顶级屏幕之后 以下是用户在菜单上选择“添加节点”选项时执行的代码: (defun node-add-mode (canvas) (configure canvas :cursor "cross") (bind canvas "<B

我正在使用ltk为CommonLisp中的Dijkstra算法开发一个GUI应用程序。但是,要将节点放置在画布上,我需要它的标签,要这样做,执行必须等到用户输入字符串(并按Return键)以使用此值启动节点实例。在没有监听过程的情况下,返回发生在创建第二个顶级屏幕之后

以下是用户在菜单上选择“添加节点”选项时执行的代码:

(defun node-add-mode (canvas)
  (configure canvas :cursor "cross")
  (bind canvas "<ButtonPress-1>"
    (lambda (evt)
      (let* ((pos-x (event-x evt))
         (pos-y (event-y evt))
         (data (read-node-data))
         (node (make-instance 'node :pos (list pos-x pos-y) :data data)))
        (populate-graph :node node)
        (create-graph canvas *graph*)))))
我只想在
事件发生后返回此代码块中的输入文本,以便能够将其传递给节点实例化。

Tcl有一种机制,用于代码需要阻塞某些变量值的情况。据我所知,这是没有在LTK。您可以使用另一个系统,如
cl async
,但最简单的选择可能是将代码从内到外转换,使其成为基于事件的:仅在名称已知时构建节点

(defun read-node-data (continuation)
  ...
  (bind v 
    "<Return>" 
    (lambda (evt &aux (text (text evt)))
      (destroy m)
      (funcall continuation text))))
(取消读取节点数据(续)
...
(约束)
"" 
(lambda(evt&aux(text(text evt)))
(m)
(全文续)
然后:

(defun node-add-mode (canvas)
  (configure canvas :cursor "cross")
  (bind canvas "<ButtonPress-1>"
        (lambda (evt)
          (let ((pos-x (event-x evt))
                (pos-y (event-y evt)))
            (read-node-data
             (lambda (data)
               (let ((node (make-instance 'node
                                          :pos (list pos-x pos-y)
                                          :data data)))
                 (populate-graph :node node)
                 (create-graph canvas *graph*))))))))
(定义节点添加模式(画布)
(配置画布:光标“交叉”)
(绑定画布“”
(lambda(evt)
(let((位置x(事件x evt))
(位置y(事件y evt)))
(读取节点数据)
(lambda(数据)
(let((节点)(生成实例)节点
:pos(列表pos-x pos-y)
:数据()
(填充图形:节点)
(创建图形画布*图形*(()()()())))

实际发生了什么?你能提供一个最小的可复制的例子,我们可以复制粘贴并运行吗?
(defun node-add-mode (canvas)
  (configure canvas :cursor "cross")
  (bind canvas "<ButtonPress-1>"
        (lambda (evt)
          (let ((pos-x (event-x evt))
                (pos-y (event-y evt)))
            (read-node-data
             (lambda (data)
               (let ((node (make-instance 'node
                                          :pos (list pos-x pos-y)
                                          :data data)))
                 (populate-graph :node node)
                 (create-graph canvas *graph*))))))))