【问题标题】:How can I pass multiple commands using Tkinter?如何使用 Tkinter 传递多个命令?
【发布时间】:2020-11-30 15:25:59
【问题描述】:

例如我有

root = Tk()
root.geometry("650x500+0+0")
def do_it():
    print("1st function")
def do_it1():
    print("2nd function")
button = Button(root,text="Change Config", width=20, height=3, bg="#26d142",fg="#030208", command=do_it)

但我希望它通过 2 个命令 就像

button = Button(root,text="Change Config", width=20, height=3, bg="#26d142",fg="#030208", command=do_it, do_it1)

【问题讨论】:

  • 使用lambda :do_it(xx,xx)functools.partial
  • 只需创建运行do_it()do_it1() 的新函数,然后使用此函数command=new_function
  • command=lambda: (do_it(), do_it1()).

标签: python function tkinter command


【解决方案1】:

最简单的方法是创建一个新的函数来运行这两个函数并将其与 Button 一起使用

def do_it():
    print("1st function")
def do_it1():
    print("2nd function")

def new_function():
    do_it()
    do_it1()

button = Button(root,text="Change Config", command=new_function)

正如@acw1668 在评论中显示的那样,您可以使用lambda 将其写得更短

button = tk.Button(root,text="Change Config", command=lambda:(do_it(), do_it1()))

但有时它的可读性可能会降低。


编辑:

使用bind(..., add="+"),您还可以为同一个小部件和事件分配许多功能。对bindunbind 功能之一可能有用,但我不知道您是否可以保持功能顺序。

它需要在函数中获取参数(event)。它需要定义自己的unbind(),因为原来的unbind() 不能按预期工作,它会删除所有功能,而只选择一个。

我从Deleting and changing a tkinter event binding 得到了unbid()

import tkinter as tk

# --- functions ---

def unbind(widget, sequence, funcid=None):
    """Unbind for this widget for event SEQUENCE the function identified with FUNCID."""

    # remove all functions
    if not funcid:
        widget.tk.call('bind', widget._w, sequence, '')
        return
    
    # get list with all functions
    func_callbacks = widget.tk.call('bind', widget._w, sequence, None).split('\n')
    # remove one function from list
    new_callbacks = [l for l in func_callbacks if l[6:6 + len(funcid)] != funcid]
    # bind again other functions
    widget.tk.call('bind', widget._w, sequence, '\n'.join(new_callbacks))
    # clear
    widget.deletecommand(funcid)

def do_it(event=None):
    print("1st function")
    unbind(button, '<Button 1>', bind_id1)
    
def do_it1(event=None):
    print("2nd function")

def new_function():
    do_it()
    do_it1()

# --- main ---

root = tk.Tk()

button = tk.Button(root,text="Button 1", command=new_function)
button.pack()

button = tk.Button(root,text="Button 2", command=lambda:(do_it(), do_it1()))
button.pack()

button = tk.Button(root,text="Button 3")
button.pack()

bind_id1 = button.bind('<Button 1>', do_it, add="+")
bind_id2 = button.bind('<Button 1>', do_it1, add="+")
print(bind_id1)

root.mainloop()

【讨论】:

  • 这不是一个好的 OOP 解决方案。这只会让 OP 的坏主意变得更糟。如果有的话,他们应该只从doit 调用doit1,如果有必要,将一个标志传递给doit,以确定是否应该调用doit1。如果您看到了您所建议的程序集,您就会明白为什么这不是一个好建议。你只是到处乱跳......从new_functiondoit,回到new_functiondoit1,然后回到new_function,它最终终止了。所有这些都可以调用 2 个函数。
  • @MichaelGuidry 你把它复杂化了。
  • 不,我没有。你不了解全部范围。不过,我愿意。如果有人把事情复杂化了,那就是你。将 2 个函数调用包装在第三个函数中以进行访问,效率低下、不必要且完全愚蠢。
  • @MichaelGuidry:这如何让一个坏主意变得更糟?可以说,鉴于 OP 当前的实现,这是最好的解决方案。这正是函数的用途——调用其他代码。此解决方案干净、简单、易于理解、易于调试,并且有效。
猜你喜欢
  • 2014-09-11
  • 1970-01-01
  • 1970-01-01
  • 2012-06-02
  • 2013-03-20
  • 1970-01-01
  • 1970-01-01
  • 2011-10-18
相关资源
最近更新 更多