1

我正在 AMD64 机器上使用 SBCL for Linux。
函数 ANIMTEST 用 CANVAS 小部件实例化一个 LTK 窗口。两个项目,BARRIER 和 FOLLOWER,存在于画布中。两者都连续旋转,BARRIER 位于画布中心,FOLLOWER 旨在跟随鼠标,但未按预期工作。我的第一次尝试(见评论)导致鼠标的绝对屏幕坐标被解释为画布内的相对坐标,而不考虑两者之间的偏移。在搜索 ltk.lisp 和文档后,我找到了 SCREEN-MOUSE-X/Y(第二次尝试,见评论)。根据文档,我觉得我正在使用 SCREEN-MOUSE-X & -Y,但为什么它不起作用?= 注意 = 包含 ANIMTEST 的文件和支持它的包可以正常加载和运行。我定义的函数(UCTK-BEAM 等)经过测试并且运行良好。

(defun animtest ()
      "Test a spinning figure in LTK"
      (with-ltk ()
        (let* ((cnvs (make-instance 'canvas :width 400 :height 400))
           (barrier (uctk-beam 200 200 40 20))
           (follower (uctk-beam 0 40 40 20))
           (slp-time 50) ; in ms
           (bar-theta 0)
           (fol-theta 0))
          (labels ((update ()
             (draw barrier nil)
             (draw follower nil)
             (incf bar-theta (/ pi 15))
             (incf fol-theta (/ pi 15))
             (geo:set-theta barrier bar-theta)
             (geo:set-theta follower fol-theta)
             (geo:set-center follower 
                     ;== FIRST ATTEMPT ==
                     (cons (screen-mouse-x cnvs)
                       (screen-mouse-y cnvs)))
                     ; == SECOND ATTEMPT ==
                     ;(cons (canvasx cnvs (screen-mouse-x cnvs))
                    ;   (canvasy cnvs (screen-mouse-y cnvs))))
             (after slp-time #'update)))
        (pack cnvs :fill :both :expand 1)
        (update)))))

提前致谢!

4

2 回答 2

2

为了在画布小部件中获取鼠标位置,我不调用屏幕鼠标函数,而是绑定动作和按钮按下事件。回调传递了包含插槽 event-x 和 event-y 的事件结构,它们是画布坐标。通过这种方式,您不仅可以直接获得正确的值,而且效率更高,因为您不必轮询鼠标位置——当它发生变化时,您会自动获得更新。在您的情况下,您可以选择在鼠标移动时更新屏障,或者将鼠标坐标存储在您在更新循环中读取的变量中。

于 2012-07-20T07:23:29.267 回答
1

尽管 CANVASX/Y 函数似乎仍然无法按预期工作,但 LTK 提供了 WINDOW-X/-Y 来返回小部件的 X 和 Y 屏幕坐标,以便您可以编写以下代码来达到预期的效果:

(cons (- (screen-mouse-x) (window-x cnvs))
      (- (screen-mouse-y) (window-y cnvs)))

这假定鼠标光标与名为 CNVS 的画布小部件位于同一屏幕上。

于 2012-07-08T21:34:48.423 回答