首页 > 解决方案 > 如何等到事件结束后使用 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>"事件发生后从该代码块返回条目文本,以便能够将其传递给节点实例化。

标签: common-lispltk

解决方案


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

推荐阅读