【问题标题】:Getting the widget that triggered an Event?获取触发事件的小部件?
【发布时间】:2010-11-28 21:21:13
【问题描述】:

在 Tkinter 中,我有多个小部件绑定到鼠标左键。单击时它们都会触发相同的事件。

如何恢复点击了哪个小部件?

我想要它,所以当说Label2 被按下时,我能够恢复Label2 是在它触发的事件中被按下的小部件。

【问题讨论】:

    标签: python events widget tkinter


    【解决方案1】:
    def f(event):
        caller = event.widget
    

    【讨论】:

    • 这假定小部件提供event。例如,在按钮的非常简单的情况下,情况并非如此(至少对于单击按钮)。
    【解决方案2】:

    您有几个选择。一种方法是访问事件对象的widget 属性。另一种方法是将对象引用传递给您的函数。这是一个使用每种方法的示例。

    import Tkinter as tk
    
    def onClickA(event):
        print "you clicked on", event.widget
        event.widget.config(text="Thank you!")
    
    
    def onClickB(event, obj):
        print "you clicked on", obj
        obj.config(text="Thank you!")
    
    root = tk.Tk()
    l1 = tk.Label(root, text="Click me")
    l2 = tk.Label(root, text="No, click me!")
    l1.pack()
    l2.pack()
    
    l1.bind("<1>", onClickA)
    l2.bind("<1>", lambda event, obj=l2: onClickB(event, obj))
    
    root.mainloop()
    

    【讨论】:

      【解决方案3】:

      听起来您的所有小部件都共享一个事件处理程序。这段摘自 John W. Shipman - NM Tech 的 Tkinter 8.5 Reference 可能会有所帮助。

      54.7. The extra arguments trick

      有时你想通过其他 处理程序的参数除了 事件。

      这是一个例子。假设你的 应用程序有一个十个数组 存储小部件的检查按钮 在self.cbList 列表中,索引为 range(10) 中的复选框编号。

      进一步假设你想写 一个名为 .__cbHandler 的处理程序用于 &lt;Button-1&gt; 全部十个事件 这些复选按钮。处理程序可以 获取实际的 Checkbutton 小部件 通过引用 Event.widget 属性 传入的对象,但是如何 它是否发现检查按钮的 self.cbList中的索引?

      编写我们的处理程序会很好 有一个额外的论据 复选按钮编号,类似于 这个:

          def __cbHandler(self, event, cbNumber):
      

      但事件处理程序只传递一个 论据,事件。所以我们不能使用 上面的功能是因为 参数数量不匹配。

      幸运的是,Python 的能力 为函数提供默认值 争论给了我们一条出路。有一个 看看这段代码:

          def __createWidgets(self):
              ...
              self.cbList = []  # Create the checkbutton list
              for i in range(10):
                  cb = Checkbutton(self, ...)
                  self.cbList.append(cb)
                  cb.grid(row=1, column=i)
                  def handler(event, self=self, i=i):  # [1]
                      return self.__cbHandler(event, i)
                  cb.bind("<Button-1>", handler)
              ...
          def __cbHandler(self, event, cbNumber):
              ...
      

      [1] 这些行定义了一个新函数 handler 预计三个 论据。第一个论点是 Event 对象传递给所有事件 处理程序,以及第二个和第三个 参数将设置为默认值 价值观?我们需要的额外参数 通过吧。

      这种技术可以扩展到 提供任意数量的额外 处理程序的参数。

      像@Bryan Oakley 为his answer 中的第二个按钮所做的那样,一种更简洁的方法是使用lambda 表达式内联定义每个处理函数,即:

      def __createWidgets(self):
          ...
          self.cbList = [] # Create the checkbutton list
          for i in range(10):
              cb = Checkbutton(self, ...)
              self.cbList.append(cb)
              cb.grid(row=1, column=i)
              cb.bind("<Button-1>", lambda event, self=self, i=i:
                                      self.__cbHandler(event, i))
          ...
      def __cbHandler(self, event, cbNumber):
          ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-08
        相关资源
        最近更新 更多