2012-07-07 72 views
1

我正在AMD64机器上使用SBCL for Linux。
功能ANIMTEST使用CANVAS小部件实例化LTK窗口。两件物品BARRIER和FOLLOWER住在画布上。两者都连续旋转,BARRIER位于画布的中心,FOLLOWER意图跟随鼠标,该鼠标不按预期工作。我的第一次尝试(见注释)导致鼠标的绝对屏幕坐标被解释为画布内的相对坐标,而不考虑两者之间的偏移。在搜索完ltk.lisp和文档后,我找到了SCREEN-MOUSE-X/Y(第二次尝试,请参阅评论)。我觉得我根据文档使用SCREEN-MOUSE-X & -Y,但它为什么不起作用? = Note = 包含ANIMTEST的文件及支持它的包加载并运行时没有错误。 我定义的函数(UCTK-BEAM等)已经过测试并运行良好。无法访问与CANVAS小部件相关的鼠标坐标

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

提前感谢!

回答

2

要抓住画布窗口小部件中的鼠标位置,我不会调用 屏幕鼠标功能,而是绑定动作和按钮按下 事件。该回调获得了包含 事件结构的事件结构,该事件结构包含作为画布坐标的槽event-x和event-y。不仅 能够以这种方式直接获取正确的值,而且因为您不必轮询鼠标位置,所以它的效率更高,因为 效率更高,您可以在更改时自动更新 。在你的情况下,你可以选择 更新鼠标移动的屏障,或者, 将鼠标坐标存储在你更新 循环内的一个变量中。

1

虽然CANVASX/Y函数仍然不能按预期工作,但LTK提供WINDOW-X/-Y返回小部件的X和Y屏幕坐标,以便您可以编写以下内容以实现所需效果:

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

这假定该鼠标光标是在同一屏幕命名的CNV画布组件上。