Tkinter 将带参数的函数绑定到小部件

发布于 2024-12-03 01:11:27 字数 441 浏览 1 评论 0原文

我有一个 tkinter 框架和一个附加到它的按钮:

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南城追梦 2024-12-10 01:11:27

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

当您使用 command 属性时,包含此参数。您必须在每种情况下如何调用函数或函数如何解释其参数时小心考虑此额外参数。

下面是一种解决方案,它在绑定中使用 lambda 来仅在使用 Bind 命令时接受额外事件,但不将其传递给最终命令。

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 方法)或顶级小部件。

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.

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.

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

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.

断桥再见 2024-12-10 01:11:27

怎么样:

import tkinter as tk


def rand_func(eff=None, a=1, b=2, c=3):
    print(a + b + c)

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

frame = tk.Frame(root)
frame.pack()

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

root.mainloop()

How about:

import tkinter as tk


def rand_func(eff=None, a=1, b=2, c=3):
    print(a + b + c)

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

frame = tk.Frame(root)
frame.pack()

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

root.mainloop()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文