用鼠标指针移动蟒龟

问题描述:

我一直在尝试保存图像,为我的手写文本识别项目捕获手写文本。为此目的,我正在使用蟒蛇龟。我想通过移动鼠标来改变画布上的乌龟坐标(在笔的位置),并通过按住鼠标左键移动鼠标来使其写入(在笔向下的位置)。我无法实现这一点。这是我的代码。用鼠标指针移动蟒龟

import tkinter 
import turtle 

sc = tkinter.Tk() 
sc.geometry("1000x1000+100+100") 

fr4 = tkinter.Frame(sc, height=500, width=600, bd=4, bg="light green", takefocus="", relief=tkinter.SUNKEN) 

fr4.grid(row=2, column=2, sticky=(tkinter.N, tkinter.E, tkinter.W, tkinter.S)) 

# Canvas 
canvas = tkinter.Canvas(fr4, width=1920, height=1080) 
canvas.pack() 

# Turtle 
turtle1 = turtle.RawTurtle(canvas) 
turtle1.color("black") 
turtle1.shape("turtle") 
turtle1.speed(100000) 

def drag_handler(x, y): 
    turtle1.ondrag(None) # disable event inside event handler 
    turtle1.goto(x, y) 
    turtle1.ondrag(drag_handler) # reenable event on event handler exit 

turtle1.ondrag(drag_handler) 

sc.mainloop() 
+1

请注意比“我无法执行此操作”更清楚地了解问题。究竟什么不是你想要的?如果有错误,完整的追溯是什么?请参见[如何创建最小,完整和可验证示例](http://*.com/help/mcve)。 –

+0

如果您想用鼠标拖动乌龟 – eyllanesc

+0

@eyllanesc,请重新阅读他的描述。他希望tutle能够*始终*追踪鼠标,只有当鼠标左键落下时才留下踪迹。提供的代码不会拖动n绘图,但不会跟踪何时未按下鼠标按钮。 – cdlane

下面是我介绍的内容。我已经把它从Tk中移出来,直接转换成了乌龟。但是,我介绍低级别的Tk调用来实现缺少的海龟onmove()事件处理程序。一旦到位,它就成为管理运动,点击,发布和拖动的问题。确保先单击窗口的标题栏,使其活跃:

from turtle import Turtle, Screen 

MOVING, DRAGGING = range(2) # states 

def move_handler(x, y): 
    if state != MOVING: # ignore stray events 
     return 

    onmove(screen, None) # avoid overlapping events 
    yertle.penup() 
    yertle.setheading(yertle.towards(x, y)) 
    yertle.goto(x, y) 
    onmove(screen, move_handler) 

def click_handler(x, y): 
    global state 

    yertle.onclick(None) # disable until release 
    onmove(screen, None) # disable competing handler 

    yertle.onrelease(release_handler) # watch for release event 
    yertle.ondrag(drag_handler) # motion is now dragging until release 

    state = DRAGGING 

def release_handler(x, y): 
    global state 

    yertle.onrelease(None) # disable until click 
    yertle.ondrag(None) # disable competing handler 

    yertle.onclick(click_handler) # watch for click event 
    onmove(screen, move_handler) # dragging is now motion until click 

    state = MOVING 

def drag_handler(x, y): 
    if state != DRAGGING: # ignore stray events 
     return 

    yertle.ondrag(None) # disable event inside event handler 
    yertle.pendown() 
    yertle.setheading(yertle.towards(x, y)) 
    yertle.goto(x, y) 
    yertle.ondrag(drag_handler) # reenable event on event handler exit 

def onmove(self, fun, add=None): 
    """ 
    Bind fun to mouse-motion event on screen. 

    Arguments: 
    self -- the singular screen instance 
    fun -- a function with two arguments, the coordinates 
     of the mouse cursor on the canvas. 

    Example: 

    >>> onmove(turtle.Screen(), lambda x, y: print(x, y)) 
    >>> # Subsequently moving the cursor on the screen will 
    >>> # print the cursor position to the console 
    >>> screen.onmove(None) 
    """ 

    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) 

screen = Screen() 
screen.setup(500, 600) 
screen.screensize(1920, 1080) 

yertle = Turtle('turtle') 
yertle.speed('fastest') 

state = MOVING 

# Initially we track the turtle's motion and left button clicks 
onmove(screen, move_handler) # a la screen.onmove(move_handler) 
yertle.onclick(click_handler) # a click will turn motion into drag 

screen.mainloop() 

onmove()事件的实现是从我的回答对Find the cursor's current position in Python turtle,随时给它,当你访问一个给予好评。 (就像你的drag_handler()来自我对Turtle freehand drawing的回答,如果你还没有,请随时给予一个赞成票。)

+0

这个实现在鼠标移动速度缓慢的情况下工作得很好,但是当它更随意(像某人的写作)时,就会出现错误。有时候,乌龟不会留下踪迹,有时它只能在拖曳的初始位置和最终位置之间画出一条直线。 – TheBeginner

+0

@TheBeginner,我检测了代码,发现它产生了意想不到的运动事件,所以我添加了一个显式的状态变量来过滤掉这些错误。它吸引了更多的清洁工 - 如果你需要它是完美的,你可能会考虑信号量和锁定。 – cdlane