【问题标题】:How do I get mouse position with tkinter and turtle?如何使用 tkinter 和 turtle 获得鼠标位置?
【发布时间】:2019-06-08 01:08:52
【问题描述】:

我正在尝试制作一个程序,让我可以使用海龟在 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

我希望光标位于箭头的顶部,但它始终位于右下方。另外,当我向上移动鼠标时,箭头会向下移​​动,反之亦然。

【问题讨论】:

    标签: python tkinter turtle-graphics


    【解决方案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
    

    【讨论】:

    • 这在我的系统上不起作用——鼠标只是在一定程度上跟踪光标,但它自己也会飞来飞去,程序很快就会失败,并出现“Python 意外退出”弹出面板和一个“中止”到控制台。
    【解决方案2】:

    您遇到的问题不是您自己造成的。一般规则是在海龟画布中使用海龟方法。但是 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()
    

    【讨论】:

    • 非常感谢,这解决了我的问题并帮助缩短了我的代码。你可能猜到我是编程新手,但你解释了我不知道的事情,我很感激..
    【解决方案3】:

    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()
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      • 2018-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-18
      相关资源
      最近更新 更多