3

我想根据选择的单选按钮更改按钮的功能和文本。现在发生的情况是,一旦启动应用程序,两个命令就会同时运行,而不是基于选择了哪个单选按钮。

import tkinter as tk
import time

## Time variables for the Pomodoro
pomo = 60 * 25 ## 60 seconds times number of minutes
btime = 60 * 5 ## 60

class ExampleApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)        
        self.label = tk.Label(self, text="25:00", width=10, font="Helvetica 20")
        self.label.pack()
        self.remaining = 0
        self.button = tk.Button(self)
        self.button.pack()

        pomocommand = self.button.configure(text="Pomodoro", state=tk.NORMAL, command= lambda: self.pomodoro(pomo)) #Switch back to the pomodoro timer
        breakcommand = self.button.configure(text="Break", state=tk.NORMAL, command= lambda: self.breaktime(btime)) #Switch to the break timer

        countercommand = self.button.configure(text="Counter", state=tk.NORMAL, command= print('cheese'))

        self.radvar = tk.IntVar()
        self.radvar.set('1')
        self.radio = tk.Radiobutton(self, text="Pomodoro", variable = self.radvar, value=1, indicatoron=0, command = pomocommand)
        self.radio.pack(anchor=tk.W)
        self.radio = tk.Radiobutton(self, text="Counter", variable = self.radvar, value=2, indicatoron=0, command = countercommand)
        self.radio.pack(side=tk.LEFT)

    def pomodoro(self, remaining = None):
        self.button.configure(state=tk.DISABLED)
        if remaining is not None:
            self.remaining = remaining

        if self.remaining <= 0:
            self.label.configure(text="Time's up!")
            breakcommand
        else:
            self.label.configure(text= time.strftime('%M:%S', time.gmtime(self.remaining))) #Integer to 'Minutes' and 'Seconds'
            self.remaining = self.remaining - 1
            self.after(1000, self.pomodoro)


    def breaktime(self, remaining = None):
        self.button.configure(state=tk.DISABLED)
        if remaining is not None:
            self.remaining = remaining

        if self.remaining <= 0:
            self.label.configure(text="Time's up!")
            pomocommand
        else:
            self.label.configure(text= time.strftime('%M:%S', time.gmtime(self.remaining))) #Integer to 'Minutes' and 'Seconds'
            self.remaining = self.remaining - 1
            self.after(1000, self.breaktime)

if __name__ == "__main__":
    app = ExampleApp()
    app.mainloop()
4

1 回答 1

4

您正在做的是调用函数self.button.configure(...)而不是传递函数本身。这是一个小例子:

def test(a):
    return a+4

callback_1 = test(2) # callback_1 will be (2+4) = 6, because you called the function. Notice the parens ()
callback_2 = test    # callback_2 will be the function test, you did not call it
# So, you can do:
callback_2(some_value) # will return (some_value + 4), here you called it

基本上发生的事情是您正在使用第一个示例,因此该函数被调用 in __init__,并且应该在那里完成它应该做的事情。你想要的是类似于第二个的东西,因为 Tkinter 想要调用一些东西(一个函数或 any callable)。所以应该是函数pomocommandbreak不是调用函数的结果。(你可以尝试做print pomocommand,看看它不是一个函数。)

解决方案是要么创建一个新函数,要么使用 lambdas。这里:

def pomocommand(self):
    pomocommand = self.button.configure(text="Pomodoro", state=tk.NORMAL, command= lambda: self.pomodoro(pomo)) #Switch back to the pomodoro timer

# and in your __init__ method:
def __init__(self):
    # ...
    self.radio = tk.Radiobutton(self, text="Pomodoro", variable = self.radvar, value=1, indicatoron=0, command = self.pomocommand)
    # ...

你对另一个按钮做同样的事情。不建议在此处使用 lambda,因为它是一个很长的语句(self.button.configure 部分),因此您的代码将不可读。但我看到你正在使用 lambda,所以你可能会明白。

作为旁注,像你一样使用 lambda 时要小心。这pomo是一个全局变量,但如果不是,您可能会遇到麻烦。看到这个问题。(现在没关系,所以你可以忽略这个:D)。

于 2012-05-16T08:26:38.377 回答