McCLIM, как поймать нажатие клавиши? - PullRequest
0 голосов
/ 05 ноября 2018

Я сейчас изучаю 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"))

1 Ответ

0 голосов
/ 06 ноября 2018
(defun show (text)
   (setf (gadget-value (slot-value *application-frame* 'text-field))
         text))

В приведенной выше функции вы пытаетесь получить гаджет из слота. Это не способ сделать. Используйте вместо этого FIND-PANE-NAMED. Дайте ему рамку и название панели. Он вернет эту панель.

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

Опять же, теперь вы используете SHOW в совершенно ином контексте. Теперь он ДОЛЖЕН вернуть 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. Здесь вы просто определяете макет.

...