如何使用ltk等到事件结论从函数返回?

时间:2019-06-16 18:05:46

标签: common-lisp ltk

我正在使用ltk开发Common-Lisp中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*)))))

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>"事件之后才从此代码块返回输入文本,以便将其传递给节点实例化。

1 个答案:

答案 0 :(得分:2)

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*))))))))