我正在尝试制作一个程序,使我可以使用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
我希望光标位于箭头的上方,但始终位于右侧和下方。另外,当我向上移动鼠标时,箭头向下移动,反之亦然。
答案 0 :(得分:1)
认真思考如何设置setworldcoordinate()。 -500-500表示您的世界大小为1,000,窗口大小为500。此外,鼠标指针与窗口根的偏移量-应该使用两个绝对坐标。您混合使用了绝对坐标-鼠标指针和vrootx,它们的缩放比例不同,因此两者之间的距离毫无意义。以下代码可能更接近您的预期。请注意,我将世界坐标设置为与鼠标指针从窗口的上/左角偏移的绝对坐标相匹配。
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(0,500,500,0)
window.bgcolor("white")
frame = tk.Frame(root)
frame.pack(side = tk.RIGHT,fill=tk.BOTH)
pointLabel = tk.Label(frame,text="Width")
pointLabel.pack()
print(dir(root))
def getPosition(event):
x = root.winfo_pointerx()-root.winfo_rootx()
y = root.winfo_pointery()-root.winfo_rooty()
print(x, y)
pen.goto(x,y)
pass
cv.bind("<Motion>", getPosition)
cv.pack
tk.mainloop()
pass
if __name__ == "__main__":
main()
pass
答案 1 :(得分:0)
Tkinter的鼠标位置:
import Tkinter as tk
root = tk.Tk()
def motion(event):
x, y = event.x, event.y
print('{}, {}'.format(x, y))
root.bind('<Motion>', motion)
root.mainloop()
乌龟的鼠标位置:
canvas = turtle.getcanvas()
x, y = canvas.winfo_pointerx(), canvas.winfo_pointery()
希望这会有所帮助。
答案 2 :(得分:0)
您遇到的问题不是您自己造成的。一般规则是在乌龟画布中使用乌龟方法。但是turtle没有固有的'Motion'事件类型,因此您尝试使用原始的Canvas
作为替代。因此发生冲突。
您自己遇到的一个问题是,当您处于快速移动的事件处理程序中时,首先需要禁用事件处理程序,然后在退出时重新启用。否则,事件会重叠并且发生坏事。 (无意的递归和其他困扰。)
我已经在下面重写了您的程序,使其可以正常运行。解决方法是添加缺少的turtle方法,这样我们就可以保留在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()