【问题标题】:In tkinter, how to make custom child widget receive mouse scroll event?在 tkinter 中,如何使自定义子小部件接收鼠标滚动事件?
【发布时间】:2012-07-18 21:52:28
【问题描述】:

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

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()

【问题讨论】:

    标签: python user-interface tkinter


    【解决方案1】:

    所以为了让一个框架接收事件,它需要有焦点。你可以在上面调用frame.set_focus(),但是一旦你给了另一个小部件焦点,它就不起作用了。为了解决这个问题,我们可以将&lt;Button-1&gt; 绑定到框架并将焦点设置到框架,但是您的画布占据了框架的整个大小,因此您需要将&lt;Button-1&gt; 事件绑定到该框架。

    添加:

    self.canvas.bind("<Button-1>", lambda _: self.focus_set())
    

    CustomWidget.__init__ 中的其他绑定之后,只要小部件具有焦点,您的绑定就会工作,当用户单击它时它就会工作(类似于列表框的工作方式)。如果画布从来没有像框架那么大,您可能需要向框架添加另一个 &lt;Button-1&gt; 绑定。

    【讨论】:

      猜你喜欢
      • 2020-10-24
      • 2013-07-02
      • 2016-05-30
      • 1970-01-01
      • 2023-02-10
      • 2021-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多