无法从tkinter widget.after函数传递参数

Bra*_*ers 4 python arguments window tkinter popup

我正在使用tkinter构建的GUI的一部分有一个弹出窗口,上面写着"请等待程序运行".然后它完成后窗户就会消失.我正在使用widget.after命令打开窗口并运行命令.但是,如果我传递函数我调用参数然后弹出窗口永远不会发生.这是一个例子:

def backupWindow
    self.restoreCB = Toplevel()

    message = "Please wait while backup runs"
    Label(self.restoreCB, text=message, padx=100, pady=20).pack()

    widget.after(10, self.runBackup)

def runBackup(self):
    <backup code>
    self.backupCB.destroy()
Run Code Online (Sandbox Code Playgroud)

这样运行正常并按照我的要求执行操作,在备份运行时弹出窗口,然后在备份后窗口关闭.但是,如果我从widget中传递和参数,就像下面的代码一样,"请稍候"消息永远不会显示出来.

def backupWindow
    self.restoreCB = Toplevel()

    message = "Please wait while backup runs"
    Label(self.restoreCB, text=message, padx=100, pady=20).pack()

    widget.after(10, self.runBackup(mybackup))

def runBackup(self,mybackup):
    <backup code using mybackup>
    self.backupCB.destroy()
Run Code Online (Sandbox Code Playgroud)

Bry*_*ley 19

当你这样做:

widget.after(10, self.runBackup(mybackup))
Run Code Online (Sandbox Code Playgroud)

...你告诉Tkinter"运行命令runBackup,当它返回时,使用结果作为参数after".因为runBackup退货None,以上相当于:

self.runBackup(mybackup)
widget.after(10, None)
Run Code Online (Sandbox Code Playgroud)

相反,您希望提供对函数after引用,而不是调用函数.如果命令需要参数,则可以将这些after参数作为附加参数.

例如:

widget.after(10, self.runBackup, mybackup)
Run Code Online (Sandbox Code Playgroud)

  • 为了完整起见,结果调用是“widget.after(10, None)”,因为没有 return 语句的函数返回“None”。 (2认同)

Joh*_*Jr. 1

我会尝试 functools.partial 来包装您的呼叫,如下所示:

widget.after(10, functools.partial(self.runBackup, mybackup))
Run Code Online (Sandbox Code Playgroud)

或者您可以定义一个不带参数但传递参数的本地函数(这本质上就是 functools.partial 的作用)。

  • 虽然这是一个完全可以接受的解决方案,但它比需要的更复杂。`after` 被设计为接受参数,并在调用函数时使用它们,OP 只是做错了。 (4认同)
  • 在这个简单的情况下,您可以只使用 lambda 来定义匿名函数,而不是 functools.partial:widget.after(10, lambda: self.runBackup(mybackup)) (3认同)