Tkinter 将带参数的函数绑定到小部件 [英] Tkinter binding a function with arguments to a widget

查看:27
本文介绍了Tkinter 将带参数的函数绑定到小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 tkinter 框架和一个按钮:

I have a tkinter frame and a button attached to it:

from tkinter import *

def rand_func(a,b,c,effects):
    print (a+b+c)

root=Tk()
frame=Frame(root)
frame.bind("<Return>",lambda a=10, b=20, c=30: rand_func(a,b,c))
frame.pack()

button=Button(frame, text="click me", command=lambda a=1,b=2,c=3,eff=None:rand_func(a,b,c))
button.pack()

root.mainloop()

我希望在用户按下 Enter 和按下按钮时执行相同的功能.遗憾的是,上面的代码在帧绑定时出现了错误.有人知道这个问题的解决方案吗?

I want the same function to be done when user presses enter and when he presses the button. Sadly, the code above gives an error at the frame binding. Does anyone know a solution to this problem?

推荐答案

当您使用 bind 创建绑定时,Tkinter 会自动添加一个包含事件信息的参数.您需要在 rand_func 定义或调用方式中考虑到这一点.

When you create a binding with bind, Tkinter automatically adds an argument that has information about the event. You'll need to account for that either in your rand_func definition or in how you call it.

当您使用 command 属性时,包含此参数.无论是在每种情况下如何调用函数,还是在函数解释其参数的方式中,您都必须注意考虑这个额外的参数.

This argument is not included when you use the command attribute. You must take care to account for this extra argument either in how you call the function in each case, or in how the function interprets its parameters.

这是一种在绑定中使用 lambda 的解决方案,仅在使用 bind 命令时才接受额外事件,但不将其传递给最终命令.

Here's one solution that uses lambda in the binding to accept the extra event only when using bind command, but not pass it on to the final command.

import tkinter as tk

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.frame = tk.Frame(self)
        self.frame.pack()
        self.button = tk.Button(self.frame, text="click me",
                             command=lambda a=1, b=2, c=3: 
                                self.rand_func(a, b, c))
        self.button.pack()
        self.frame.bind("<Return>", 
                        lambda event, a=10, b=20, c=30: 
                            self.rand_func(a, b, c))
        # make sure the frame has focus so the binding will work
        self.frame.focus_set()

    def rand_func(self, a, b, c):
        print "self:", self, "a:", a, "b:", b, "c:", c
        print (a+b+c)

app = SampleApp()
app.mainloop()

话虽如此,绑定到框架是正确的做法是很少见的.通常一个框架不会有键盘焦点,除非它有焦点,否则绑定永远不会触发.如果您正在设置全局绑定,您应该绑定到all"绑定标签(使用 bind_all 方法)或顶级小部件.

That being said, it's rare that binding to a frame is the right thing to do. Typically a frame won't have keyboard focus, and unless it has focus the binding will never fire. If you are setting a global binding you should either bind to the "all" binding tag (using the bind_all method) or to the toplevel widget.

这篇关于Tkinter 将带参数的函数绑定到小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆