2012-07-18 68 views
0

我无法理清如何使自定义小部件接收鼠标滚动事件。如果我绑定到根窗口,则会发生通知。如果我绑定到除窗口小部件以外的根窗口子窗口(这里是一个简单的列表框),通知也会发生(通过在移动轮子时观察列表移动来证明)。我忽略了什么?在tkinter中,如何使自定义子部件接收鼠标滚动事件?

实施例的代码,其中辊()从未被调用:

#!/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() 

回答

1

因此,为了使一帧到接收事件,它需要具有焦点。你可以打电话frame.set_focus(),但只要你给另一个部件集中它不会工作。为了解决这个问题,我们可以将<Button-1>绑定到框架,并将焦点设置到框架上,但是您的画布占据了框架的整个大小,因此您需要将<Button-1>事件绑定到该框架。

添加:

self.canvas.bind("<Button-1>", lambda _: self.focus_set()) 
在​​你的其他绑定后

会让只要部件具有焦点,它当用户点击它(类似于如何列表框作品)您的绑定工作。如果画布从未像框架一样大,则可能需要为框架添加另一个<Button-1>绑定。