McCLIM,如何捕捉击键?

McCLIM, How to catch a keystroke?

我目前正在学习 McCLIM。试图弄清楚如何定义一个命令,该命令将对击键做出反应。对于名为 superapp 的应用程序,我有一个函数

(defun show (text)
  (lambda (gadget)
    (declare (ignore gadget))
 (with-slots (text-field) *application-frame*
(setf (gadget-value text-field)
   text))))

在屏幕窗格上显示一些文本。它适用于 activate-callback 中的窗格按钮。然而,这

(define-superapp-command (com-greet :name t :keystroke (#\g :control)) ()
 (show "Hey"))

不起作用。我知道我对它的定义是正确的,因为它适用于 (frame-exit *application-frame*)。所以我只是不明白别的。

编辑:所以,这是工作变体

(define-application-frame superapp ()
 ()
 (:panes
  (tf1
   :push-button
       :label "Left"
       :activate-callback (show "HI"))
  (app :application
   :display-time nil
   :height 400
   :width 600)
  (screen :text-field))
 (:layouts
  (default
   (with-slots (text-field) *application-frame*
               (vertically ()
                screen
                (tabling (:grid t)
                 (list tf1 app)))))))

(defun show (text)
 (lambda (gadget)
   (declare (ignore gadget))
  (setf (gadget-value (find-pane-named *application-frame* 'screen)) 
    text)))

(define-superapp-command (com-greet :name t :keystroke (#\g)) ()
 (setf (gadget-value (find-pane-named *application-frame* 'screen)) 
 "text"))
(defun show (text)
   (setf (gadget-value (slot-value *application-frame* 'text-field))
         text))

在上面的函数中,您尝试从插槽中获取小工具。这不是做事的方法。请改用 FIND-PANE-NAMED。给它一个框架和窗格的名称。它将 return 那个 PANE。

(define-application-frame superapp ()
 ((text-field :initform nil))
 (:panes
  (tf1
   :push-button
       :label "Left"
       :activate-callback (show "HI"))

同样,您现在在完全不同的上下文中使用 SHOW。现在它应该 return 一个 LAMBDA,它将小工具作为参数。

  (app :application
   :display-time nil
   :height 400
   :width 600)
  (screen :text-field))
 (:layouts
  (default
   (with-slots (text-field) *application-frame*
               (vertically ()
                (setf text-field screen)
                (tabling (:grid t)
                 (list tf1 app)))))))

现在 :layouts 中的代码看起来不对。您不应该在那里设置插槽文本字段。实际上你根本不应该有一个插槽 TEXT-FIELD。只需在回调中使用函数 FIND-PANE-NAMED。这里你只是定义一个布局。