我无法理清如何使自定义小部件接收鼠标滚动事件。如果我绑定到根窗口,则会发生通知。如果我绑定到除了我的小部件之外的根窗口的子节点(这里是一个简单的列表框),也会发生通知(通过在移动方向盘时观察列表移动来证明)。我在俯瞰什么?
从不调用roll()的示例代码:
#!/usr/bin/python3
from tkinter import *
from tkinter.ttk import *
class CustomWidget(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.width = 200
self.height = 200
self.canvas = Canvas(self, width=200, height=200)
self.canvas.config(background='red')
self.canvas.pack()
self.bind('<MouseWheel>', self.roll)
self.bind('<Button-4>', self.roll)
self.bind('<Button-5>', self.roll)
def roll(self, event):
print("detected mouse roll!");
if __name__ == "__main__":
root = Tk()
root.wm_title("TestRoot")
sb = Scrollbar(root, orient=VERTICAL)
lb = Listbox(root, yscrollcommand=sb.set)
sb.config(command=lb.yview)
cw = CustomWidget(root)
for char in list("abcdefghijklmnopqrstuvwxyz"):
lb.insert(END, char)
cw.pack()
lb.pack()
sb.pack()
root.update()
root.mainloop()
答案 0 :(得分:1)
因此,为了使帧能够接收事件,它需要具有焦点。您可以在其上调用frame.set_focus()
,但只要您给予另一个小部件焦点,它就无法工作。为了解决这个问题,我们可以将<Button-1>
绑定到框架并将焦点设置到框架上,但是画布会占用框架的整个大小,因此您需要绑定<Button-1>
个事件相反。
添加:
self.canvas.bind("<Button-1>", lambda _: self.focus_set())
在CustomWidget.__init__
中的其他绑定之后,只要窗口小部件具有焦点,就会使绑定工作,当用户单击它时(类似于列表框如何工作)。如果画布永远不会像它的框架一样大,您可能需要在框架上添加另一个<Button-1>
绑定。