无法访问相对于CANVAS小部件的鼠标坐标

时间:2012-07-07 15:57:48

标签: linux common-lisp x86-64 sbcl ltk

我在AMD64机器上使用SBCL for Linux 函数ANIMTEST使用CANVAS小部件实例化LTK窗口。两个项目,BARRIER和FOLLOWER,住在画布上。两者都在连续旋转,BARRIER位于画布的中心,FOLLOWER意图跟随鼠标,而鼠标不能正常工作。我的第一次尝试(参见注释)导致鼠标的绝对屏幕坐标被解释为画布内的相对坐标,而没有考虑两者之间的偏移。在通过ltk.lisp和docs搜索后,我找到了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)))))

提前致谢!

2 个答案:

答案 0 :(得分:2)

要在画布小部件中抓取鼠标位置,我不会调用 屏幕鼠标功能,而是绑定动作和按钮按下 事件。回调传递包含的事件结构 slots event-x和event-y是canvas坐标。不只 你是通过这种方式直接获得正确的价值,但也是如此 更有效率,因为你不必轮询鼠标位置 - 你得到 更改时自动更新。在你的情况下你也可以 选择在鼠标移动时更新屏障,或者只是 将鼠标坐标存储在您在更新中读取的变量中 循环。

答案 1 :(得分:1)

尽管看起来CANV​​ASX / Y功能仍无法正常工作,但LTK提供WINDOW-X / -Y来返回小部件的X和Y屏幕坐标,以便您可以编写以下内容以达到所需效果:

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

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