我正在使用ltk在Common-Lisp中为Dijkstra算法开发一个GUI应用程序。然而,要在画布上放置一个节点,我需要它的标签,为此,执行必须等待,直到用户输入一个字符串(并按下Return键),以使用此值启动一个节点实例。如果没有侦听过程,返回将在创建第二个顶层屏幕之后立即发生。
下面是用户在菜单上选择"Add Node“选项时执行的代码:
(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*)))))populate-graph函数只是将创建的节点添加到实际的图形中,然后create-graph函数将其绘制在画布上。这是我到目前为止实现的read-node-data函数:
(defun read-node-data ()
(let* ((m (make-instance 'toplevel))
(f (make-instance 'frame :master m))
(l (make-instance 'label
:master f
:text "Insert The Object Value"))
(v (make-instance 'entry
:master f
:width *entry-width*)))
(wm-title m "Entry")
(pack f)
(pack l)
(pack v)
(bind v "<Return>"
(lambda (evt)
(let ((text (text v)))
(destroy m)
text)))))我希望仅在"<Return>"事件发生后才返回此代码块中的条目文本,以便能够将其传递给节点实例化。
发布于 2019-06-17 20:52:16
对于代码需要阻塞某些变量的值的情况,Tcl有一个vwait机制。据我所知,这在LTK中是不可用的。您可以使用另一个系统,如cl-async,但最简单的选择可能是将代码从内到外转换,使其成为基于事件的代码:只有在名称已知的情况下才构建节点。
(defun read-node-data (continuation)
...
(bind v
"<Return>"
(lambda (evt &aux (text (text evt)))
(destroy m)
(funcall continuation text))))然后:
(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*))))))))https://stackoverflow.com/questions/56621391
复制相似问题