如何在Python Tkinter中指定完整点击事件

1 投票
3 回答
2845 浏览
提问于 2025-04-16 03:33

下面这行Python代码会把“click”这个方法绑定到一个事件上,也就是说,当用户按下鼠标按钮时,只要鼠标指针在这个小部件上,就会触发这个方法;无论你在释放按钮时鼠标指针在哪里。

self.bind('<Button-1>',self.click)

如果我在代码中用“ButtonRelease”代替“Button”,那么“click”这个方法会在鼠标按钮释放后被调用,前提是鼠标是在按下的那个小部件上释放的;无论你在哪里释放鼠标按钮。

1- 有没有简单的方法可以让它只在鼠标按钮在我的小部件上释放时才调用绑定的方法?无论鼠标按钮在哪里按下。

2- 有没有简单的方法可以让它只在完整点击的情况下反应(也就是按下和释放都在同一个小部件上)?

3 个回答

1

在按钮释放时绑定 ButtonRelease-1 还不够。回调函数(也就是你设置的响应动作)只有在按钮被释放的时候才会触发,但无论鼠标在释放时在哪里都没关系。真正决定的,是鼠标在点击时的位置,正如 Alex Martelli 所说的那样。想要实现你想要的效果,一个简单的方法就是把所有东西放在一个画布上,然后把回调函数绑定到 ButtonRelease-1。这样你就得到了类似下面的代码:

def callback(event):
    x1, y1, x2, y2 = canvas.bbox(widget)
    if x1 <= event.x <= x2 and y1 <= event.y <= y2:
         <whatever>

我在自己的代码中也使用了这种方法,让一些普通的控件在这方面表现得像按钮一样。

4

tkinter的文档里有相关的信息可以参考:

http://www.pythonware.com/library/tkinter/introduction/events-and-bindings.htm

你可以在这里进行绑定:

<ButtonRelease-1>
5

1- 有没有简单的方法让它只在鼠标按钮释放在我的小部件上时才调用绑定的方法?无论鼠标在哪里按下?

2- 有没有简单的方法让它只在完整点击的情况下反应(在同一个小部件上按下和释放)?

没有“简单”的方法,因为正如Tkinter的文档所说:

当你在一个小部件上按下鼠标按钮时,Tkinter会自动“抓住”鼠标指针,只要鼠标按钮被按住,鼠标事件就会发送到当前的小部件。

而且你提的两个需求和这种自动抓取鼠标指针的行为是相互矛盾的(我不知道怎么禁用这个功能——我觉得可能禁用不了,但证明一个否定的事情是很难的;-)。

所以,你需要更多的工作,和一个不“简单”的解决方案:在按钮按下事件的回调中,绑定进入和离开事件(绑定到一个类实例的方法,这样你可以跟踪鼠标当前是否在你感兴趣的小部件内),以及按钮释放事件;这样,当释放事件发生时,你就知道是执行“实际应用回调”(如果在小部件内)还是不做任何事情(如果在外面)——这就满足了你的第二个需求,但把这个描述为简单就有点牵强了。

第一个需求更难,因为你必须在每个感兴趣的小部件上跟踪进入和离开事件——仅仅知道鼠标是在里面还是外面是不够的,你还必须跟踪鼠标当前在哪个小部件内(如果有的话),以便在按钮释放时正确地执行“实际应用回调”。

虽然内部实现不会很简单,但每个功能可以被绑定成一个好调用的函数……内部实现可能会稍微“复杂”(这个词通常用来形容根管治疗等,而不是编程,但在你想要打破框架中硬编码的功能时可能是合适的……这就是框架的缺点——只要你想以它们支持的方式行为,你就会很顺利,但当你想要打破它们的常规行为去做一些完全不同的事情时,这几乎永远不会是“简单”的!-)。

撰写回答