如何用鼠标按下来触发tkinter的“ <enter>”事件?

时间:2018-07-16 20:44:02

标签: python python-3.x tkinter

在带有Python 3.7的tkinter中,事件绑定的默认行为是在释放鼠标之前单击鼠标后将不触发“ ”事件。我打算实现一个可滚动的表,以便它检测到“ ”(鼠标左键单击向下)和“ ”(鼠标左键单击向上)事件以及每个表行的小部件“ ”事件绑定为检测鼠标指针何时进入其他表行。这样,我可以通过单击一行并在表中拖动来滚动表。我的假设是即使按下鼠标按钮也将触发“ ”事件,这是不正确的。因此,我的整个滚动实现都遇到了麻烦。我需要在鼠标按下时触发这些事件,否则它将无法正常工作。我正在做类似的事情:

from tkinter import *

class App:
    def __init__(self):
        self.root = Tk()
        # The name kwarg is used to infer the index of the row in the event handlers.
        self.labels = [Label(text=f"Label #{i}", name=f"row-{i}") for i in range(5)]
        for row, label in enumerate(self.labels):
            label.bind("<Button-1>", self.mouse_down)
            label.bind("<ButtonRelease-1>", self.mouse_up)
            label.bind("<Enter>", self.mouse_enter)
            label.grid(row=row, column=0)
        mainloop()

    def mouse_up(self, event):
        idx = self.index_from_event(event)
        # Do some with the row with the passed index

    def mouse_down(self, event):
        idx = self.index_from_event(event)
        # Do some with the row with the passed index

    def mouse_enter(self, event):
        # I would like for this to be triggered even when the mouse is pressed down.
        # However, by default tkinter doesn't allow this.
        pass

    def index_from_event(self, event):
        # Get the index of the row from the labels name string.
        return str(event.widget).split('-')[-1]

在tkinter中按住鼠标按钮1时,有什么方法可以启用鼠标输入事件? effbot(http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm)上的所有文档都说回车事件是:

<Enter>
    The mouse pointer entered the widget (this event doesn’t mean that the user pressed the Enter key!).

1 个答案:

答案 0 :(得分:5)

否,当按钮按下时,没有直接方法绑定到enter和离开事件,除了首先获得点击的小部件。添加该功能相当容易,但是

您可以将<B1-Motion>绑定到所有小部件,这些小部件将在鼠标移动时调用任何函数。然后,您可以使用winfo_containing方法找出光标下方的窗口小部件。有了这些信息,您就可以生成一个可以绑定到的虚拟事件(或者您可以跳过这些虚拟事件,并将代码添加到运动事件的处理程序中)。

这是一个人为的例子。单击并移动鼠标时,将调用show_info。它跟踪当前的小部件,并将其与光标下的小部件进行比较。如果不同,它将为先前的窗口小部件生成一个<<B1-Leave>>,并在新窗口小部件上生成一个<<B1-Enter>>。这些绑定将显示“你好,光标!”当光标在标签上时。

import tkinter as tk

current_widget = None
def show_info(event):
    global current_widget
    widget = event.widget.winfo_containing(event.x_root, event.y_root)
    if current_widget != widget:
        if current_widget:
            current_widget.event_generate("<<B1-Leave>>")
        current_widget = widget
        current_widget.event_generate("<<B1-Enter>>")

def on_enter(event):
    event.widget.configure(text="Hello, cursor!")

def on_leave(event):
    event.widget.configure(text="")

root = tk.Tk()
label = tk.Label(root, bd=1, relief="raised")
l1 = tk.Label(root, text="", width=20, bd=1, relief="raised")
l2 = tk.Label(root, text="", width=20, bd=1, relief="raised")

label.pack(side="top", fill="x")
l1.pack(fill="both", expand=True, padx=20, pady=20)
l2.pack(fill="both", expand=True, padx=20, pady=20)

root.bind_all("<B1-Motion>", show_info)
l1.bind("<<B1-Enter>>", on_enter)
l1.bind("<<B1-Leave>>", on_leave)
l2.bind("<<B1-Enter>>", on_enter)
l2.bind("<<B1-Leave>>", on_leave)

tk.mainloop()