2012-07-18 31 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>綁定。