2012-07-07 106 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畫布組件上。