我不知道如何让自定义小部件接收鼠标滚动事件。如果我绑定到根窗口,则会出现通知。如果我绑定到根窗口的子窗口,而不是我的小部件(这里是一个简单的列表框),通知也会发生(当我移动滚轮时,可以通过观察列表的移动来证明)。我忽略了什么?
从不调用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()发布于 2012-07-19 23:46:24
因此,为了让框架接收事件,它需要有焦点。你可以在上面调用frame.set_focus(),但是一旦你给了另一个小部件焦点,它就不能工作了。为了解决这个问题,我们可以将<Button-1>绑定到框架,并将焦点设置为框架,但是您的画布占据了整个框架的大小,因此您需要将<Button-1>事件绑定到该框架。
添加:
self.canvas.bind("<Button-1>", lambda _: self.focus_set())之后,CustomWidget.__init__中的其他绑定将使您的绑定工作,只要小部件具有焦点,当用户单击它时,它就会工作(类似于列表框的工作方式)。如果画布永远不会像它的框架那么大,那么您可能需要向框架添加另一个<Button-1>绑定。
https://stackoverflow.com/questions/11550915
复制相似问题