python - 如何使用 tkinter 和 turtle 获得鼠标位置?
问题描述
我正在尝试制作一个程序,让我使用海龟在 tkinter 窗口上绘图。由于某种原因,我无法获得绝对鼠标坐标。
我已经完成了root.winfo_pointerx() - root.winfo_rootx()
(和vrootx
)。我也试过:
def mousePos(event):
x,y = event.x , event.y
return x,y
我的代码:
import turtle
import tkinter as tk
root = tk.Tk()
root.title("Draw!")
cv = tk.Canvas(root, width=500,height=500)
cv.focus_set()
cv.pack(side = tk.LEFT)
pen = turtle.RawTurtle(cv)
window = pen.getscreen()
def main():
window.setworldcoordinates(-500,-500,500,500)
window.bgcolor("white")
frame = tk.Frame(root)
frame.pack(side = tk.RIGHT,fill=tk.BOTH)
pointLabel = tk.Label(frame,text="Width")
pointLabel.pack()
def getPosition(event):
x = root.winfo_pointerx()-root.winfo_vrootx()
y = root.winfo_pointery()-root.winfo_vrooty()
pen.goto(x,y)
cv.bind("<Motion>", getPosition)
cv.pack
tk.mainloop()
pass
我希望光标位于箭头的顶部,但它始终在右侧和向下。此外,当我向上移动鼠标时,箭头向下移动,反之亦然。
解决方案
你遇到了一个不利于你的问题,这不是你自己造成的。一般规则是在海龟画布中使用海龟方法。但是turtle 没有固有的“运动”事件类型,因此您试图使用原始事件类型Canvas
作为替代。从而产生冲突。
您自己制造的一个问题是,当您在快速移动的事件处理程序中时,您需要首先禁用事件处理程序,然后在退出时重新启用。否则,事件重叠并发生坏事。(无意的递归和其他奇怪的东西。)
我已经在下面重写了您的程序,以按照我相信您的意图工作。修复方法是添加缺失的 turtle 方法,这样我们就可以留在海龟域中:
import tkinter as tk
from turtle import RawTurtle, TurtleScreen
from functools import partial
def onscreenmove(self, fun, add=None): # method missing from turtle.py
if fun is None:
self.cv.unbind('<Motion>')
else:
def eventfun(event):
fun(self.cv.canvasx(event.x) / self.xscale, -self.cv.canvasy(event.y) / self.yscale)
self.cv.bind('<Motion>', eventfun, add)
def getPosition(x, y):
screen.onscreenmove(None) # disable events inside handler
pen.setheading(pen.towards(x, y))
pen.goto(x, y)
screen.onscreenmove(getPosition) # reenable handler on exit
root = tk.Tk()
root.title("Draw!")
cv = tk.Canvas(root, width=500, height=500)
cv.focus_set()
cv.pack(side=tk.LEFT)
screen = TurtleScreen(cv)
screen.onscreenmove = partial(onscreenmove, screen) # install missing method
pen = RawTurtle(screen)
frame = tk.Frame(root)
frame.pack(side=tk.RIGHT, fill=tk.BOTH)
tk.Label(frame, text="Width").pack()
screen.onscreenmove(getPosition)
screen.mainloop()
推荐阅读
- reactjs - 在下一个 js 中组织页面并使用 useReduser
- openoffice-calc - 如何使用 Apache Office 宏触发“行可见”
- c++ - srand() 与非常量参数一起使用时不起作用
- c# - WaitTimeSeconds 的 MassTransit 默认值
- typescript - Electron v14 TypeScript 类型定义中缺少 enableRemoteModule
- java - 从 mongodb 获取随机值
- json - JSON:键和字段名称:动态解析
- python-3.x - 数据框 - 根据给定列的先前和当前行值创建新列
- ruby-on-rails - OOP 如何转化为 Rails?
- ssh - 通过 ssh 远程启动前台程序/脚本