使用Python 3“ turtle”模块,我试图分别处理两种不同的点击条件:
现在,我可以使用两个不同的鼠标按钮来完成这项工作,就像这样:
#!/usr/local/bin/python3
import turtle
sc = turtle.Screen()
def new_turtle(x, y):
t = turtle.RawTurtle(sc, shape='circle', visible=False)
t.penup()
t.speed(0)
t.goto(x, y)
t.color('black')
t.showturtle()
t.onclick(selector(t), 2)
def deselector(t):
def deselect(x, y):
t.color('black')
t.onclick(selector(t), 2)
return deselect
def selector(t):
def select(x, y):
t.color('red')
t.onclick(deselector(t), 2)
return select
sc.onscreenclick(new_turtle, 1)
turtle.mainloop()
但是,我想用鼠标第二键做其他事情。
如果将以上代码更改为使用鼠标按钮1进行所有操作,则在按预期的方式单击时,海龟的确会更改颜色,但是onscreenclick
处理程序也 称为几乎在变色的乌龟正上方创建了一只新乌龟。
如果对乌龟的点击不是 ,有什么方法只能调用onscreenclick
处理程序吗?
答案 0 :(得分:1)
我相信以下内容将满足您的描述。如您所述,如果在同一个按钮上同时有一个屏幕按钮事件处理程序和一个乌龟按钮事件处理程序,则两者都会被触发!对于坐在tkinter之上的初学者友好的编程环境来说,这似乎是错误的。但是你有。
我下面的解决方案是让屏幕按钮事件处理程序测试单击是否可能是在乌龟上进行的,如果是,则将其忽略。这样一来,乌龟按钮事件处理程序就可以处理点击:
from turtle import Screen, Turtle
from functools import partial
CURSOR_SIZE = 20
def new_turtle(x, y):
screen.onscreenclick(None) # disable event handler inside handler
# don't respond if the click was on a turtle
if not any(t.distance(x, y) <= CURSOR_SIZE/2 for t in screen.turtles()):
t = Turtle(shape='circle', visible=False)
t.color('black')
t.penup()
t.goto(x, y)
t.showturtle()
t.onclick(partial(select, t))
screen.onscreenclick(new_turtle) # reenable event handler
def select(t, x, y):
t.color('black' if t.pencolor() == 'red' else 'red')
screen = Screen()
screen.onscreenclick(new_turtle)
screen.mainloop()
一个副作用是,在屏幕上远离海龟的位置单击会变得缓慢,因为许多海龟已添加到屏幕中,需要进行测试。为了解决这个问题,我至少在系统上注意到,在屏幕按钮事件处理程序之前 调用了海龟按钮事件处理程序。因此,诀窍是让乌龟按钮事件处理程序禁用屏幕按钮事件处理程序,但最终重新启用它:
from turtle import Screen, Turtle
from functools import partial, update_wrapper
def new_turtle(x, y):
screen.onscreenclick(None) # disable this event handler inside handler
t = Turtle(shape='circle', visible=False)
t.color('black')
t.penup()
t.goto(x, y)
t.showturtle()
t.onclick(partial(select, t))
screen.onscreenclick(new_turtle) # reenable event handler
def select(t, x, y):
screen.onscreenclick(None) # disable screen event handler inside handler
t.onclick(None) # disable this event handler inside handler
t.color('black' if t.pencolor() == 'red' else 'red')
t.onclick(partial(select, t)) # reenable this event handler
screen.ontimer(wrapper) # reenable screen event handler, eventually
screen = Screen()
wrapper = partial(screen.onscreenclick, new_turtle) # prep wrapper for later use
update_wrapper(wrapper, screen.onscreenclick)
screen.onscreenclick(new_turtle)
screen.mainloop()
这不需要检查海龟,因此不会放慢速度。 (也不要在靠近海龟的地方那样挑剔。)但是,如果时间安排不一样,则可能必须使用其他版本。