乌龟 - 如何获取窗口中鼠标光标的位置?

4

我该如何在海龟窗口中找到鼠标指针的当前位置呢?我希望在点击之前和移动光标时都能够得到鼠标位置。我已经在谷歌和这个网站上搜索过,但除了如何在点击后获取位置之外,什么也找不到。


你是否正在使用Python的turtle模块?如果是,你是否查看了文档中的"使用事件"部分? - das-g
是的。它只有onClick、click drag和on click release事件。我需要它监听鼠标指针的位置。 - helpneeded92
获取海龟屏幕中的鼠标坐标就是我所需要的,这样我就可以让海龟旋转并朝向鼠标。 - helpneeded92
2个回答

9

turtle.getcanvas() 返回一个 Tkinter 画布。

就像处理 Tkinter 窗口一样,您可以通过对其使用 winfo_pointerx.winfo_pointery 来获取当前鼠标指针的坐标:

canvas = turtle.getcanvas()
x, y = canvas.winfo_pointerx(), canvas.winfo_pointery()
# or
# x, y = canvas.winfo_pointerxy()

如果你只想对移动做出反应而不是在循环中轮询鼠标指针位置,可以注册一个事件:

def motion(event):
    x, y = event.x, event.y
    print('{}, {}'.format(x, y))

canvas = turtle.getcanvas()
canvas.bind('<Motion>', motion)

请注意,事件仅在鼠标指针悬停在海龟画布上时触发。
所有这些坐标都将是窗口坐标(原点为海龟窗口左上角的(0,0)),而不是海龟坐标(原点为画布中心的(0,0)),因此如果您想将它们用于海龟定位或方向,则需要进行一些转换。

2

这个答案的基础上,以下是通过使用canvas.bind('<Motion>', motion)方法来规范化Tkinter坐标以用于turtle的示例(canvas.winfo_pointerxy()并没有提供对我有意义的值,尽管我没有深入研究):

import turtle


def on_motion(event):
    x = event.x - turtle.window_width() / 2
    y = -event.y + turtle.window_height() / 2
    turtle.goto(x, y)
    turtle.stamp()
    print(x, y)


turtle.tracer(0)
turtle.penup()
turtle.getcanvas().bind("<Motion>", on_motion)
turtle.exitonclick()

将其用于实时应用而不仅仅是在运动中使用:

import turtle


def on_motion(event):
    global mouse_x, mouse_y
    mouse_x = event.x - turtle.window_width() / 2
    mouse_y = -event.y + turtle.window_height() / 2


def tick():
    print(mouse_x, mouse_y)
    turtle.goto(mouse_x, mouse_y)
    turtle.stamp()
    win.ontimer(tick, frame_delay_ms)


turtle.tracer(0)
mouse_x, mouse_y = 0, 0
turtle.getcanvas().bind("<Motion>", on_motion)
turtle.shape("circle")
turtle.penup()
frame_delay_ms = 1000 // 30
win = turtle.Screen()
tick()
turtle.exitonclick()

将其放入一个更全面的应用程序中,而不使用global

import turtle
from math import sin


def add_mouse_listener():
    def on_motion(event):
        nonlocal x, y
        x = event.x - turtle.window_width() / 2
        y = -event.y + turtle.window_height() / 2

    turtle.getcanvas().bind("<Motion>", on_motion)
    x, y = 0, 0
    return lambda: (x, y)


def color(c, a):
    return sin(c + a) / 2 + 0.5


def colors(r, ra, g, ga, b, ba):
    return color(r, ra), color(g, ga), color(b, ba)


def main():
    ra = 0
    ba = 0
    ga = 0
    r = 0.5
    b = 0
    g = 1
    frame_delay_ms = 1000 // 30
    turtle.tracer(0)
    turtle.pensize(40)
    mouse_pos = add_mouse_listener()
    win = turtle.Screen()

    def tick():
        nonlocal ra, ba, ga
        turtle.color(colors(r, ra, g, ga, b, ba))
        ra += 0.03
        ba += 0.0311
        ga += 0.032
        x, y = mouse_pos()
        turtle.setheading(turtle.towards(x, y))
        turtle.forward(10)
        turtle.update()
        win.ontimer(tick, frame_delay_ms)

    tick()
    turtle.exitonclick()


if __name__ == "__main__":
    main()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接