代码之家  ›  专栏  ›  技术社区  ›  Christina

如何在两种状态下使用Tkinter按钮?

  •  2
  • Christina  · 技术社区  · 7 年前

    我有以下代码,当单击Tkinter按钮时,会导致颜色/文本更改。第二次单击按钮时,我想还原为原始颜色/文本。

    from Tkinter import *
    
    window = Tk()
    window.title("Start/Stop Button")
    window.geometry('200x100')
    
    def clicked_rf1():
        btn_rf1.configure(text="Stop")
        lbl_rf1.configure(text="  ON  ", bg="green")
    
    btn_rf1 = Button(window, text="Start", command=clicked_rf1)
    btn_rf1.grid(column=1, row=1)
    lbl_rf1 = Label(window, text="  OFF ", bg="red")
    lbl_rf1.grid(column=2, row=1)
    
    window.mainloop()
    

    我想要的东西的行为更像一个切换,但我想一个按钮的外观。

    得到了感激的帮助。

    3 回复  |  直到 7 年前
        1
  •  4
  •   Novel    7 年前

    您将需要一个if块来选择要执行的操作。您可以创建另一个标志变量来跟踪状态,或者只使用当前标签或按钮文本:

    from Tkinter import *
    
    window = Tk()
    window.title("Start/Stop Button")
    window.geometry('200x100')
    
    def clicked_rf1():
        if btn_rf1['text'] == "Start":
            btn_rf1.configure(text="Stop")
            lbl_rf1.configure(text="  ON  ", bg="green")
        else:
            btn_rf1.configure(text="Start")
            lbl_rf1.configure(text="  OFF ", bg="red")
    
    btn_rf1 = Button(window, text="Start", command=clicked_rf1)
    btn_rf1.grid(column=1, row=1)
    lbl_rf1 = Label(window, text="  OFF ", bg="red")
    lbl_rf1.grid(column=2, row=1)
    
    window.mainloop()
    

    这将是创建自定义按钮子类的理想位置,因此您可以在程序中包含许多这样的子类:

    from Tkinter import *
    
    window = Tk()
    window.title("Start/Stop Button")
    window.geometry('200x100')
    
    class Christina(Frame):
        def __init__(self, master=None, **kwargs):
            Frame.__init__(self, master, **kwargs)
    
            self.btn = Button(self, text="Start", command=self.clicked)
            self.btn.grid(column=0, row=0)
            self.lbl = Label(self, text="  OFF ", bg="red")
            self.lbl.grid(column=1, row=0)
    
        def clicked(self):
            if self.btn['text'] == "Start":
                self.btn.configure(text="Stop")
                self.lbl.configure(text="  ON  ", bg="green")
            else:
                self.btn.configure(text="Start")
                self.lbl.configure(text="  OFF ", bg="red")
    
    btn1 = Christina(window)
    btn1.grid()
    btn2 = Christina(window)
    btn2.grid()
    btn3 = Christina(window)
    btn3.grid()
    
    window.mainloop()
    
        2
  •  3
  •   Bryan Oakley    7 年前

    如果需要切换,可以使用不带指示器的checkbutton。它具有“选定”和“取消选定”状态下的颜色选项,您可以将值和标签绑定在一起,以便在切换按钮时更改标签。

    像任何按钮一样,您可以将命令绑定到它。该命令可以检查变量的值,以确定它应该执行“开”功能还是“关”功能。

    下面是一个简单的示例:

    import Tkinter as tk
    
    def toggle():
        if var.get() == "ON":
            print("turning on...")
        else:
            print("turning off...")
    
    root = tk.Tk()
    var = tk.StringVar()
    toggle = tk.Checkbutton(root, onvalue="ON", offvalue="OFF", width=4,
                            indicatoron=False, 
                            variable=var, textvariable=var,
                            selectcolor="green", background="red",
                            command=toggle)
    
    var.set("OFF")
    toggle.pack()
    
    root.mainloop()
    
        3
  •  2
  •   tobias_k    7 年前

    另一种方法可能是将“一堆代码”放在不同的函数中运行,在迭代器中收集这些代码,然后获取 next 函数并执行它:

    def bunchofcode():
        print("foo")
    
    def somethingelse():
        print("bar")
    
    whattodo = iter([bunchofcode, somethingelse])
    
    def clicked_rf1():
        try:
            next(whattodo)()
        except StopIteration:
            print("nothing to do")
    

    或循环行为:

    from itertools import cycle
    whattodo = cycle([bunchofcode, somethingelse])
    

    对于双状态切换按钮,您还可以使用 dict 将当前状态映射到下一个状态。您也可以使用按钮 relief 标记状态。

    def clicked_rf1():
        transition = {"raised": "sunken", "sunken": "raised"}
        btn_rf1["relief"] = transition[btn_rf1["relief"]]