How to make button in Python Tkinter stay pressed until another one is pressed

15,127

Solution 1

So you can set the relief of the button using its config, this makes it look like it is pressed.

def save(self):
    self.button0.config(relief=SUNKEN)
    # if you also want to disable it do:
    # self.button0.config(state=tk.DISABLED)
    #...

def stop(self):
    self.button0.config(relief=RAISED)
    # if it was disabled above, then here do:
    # self.button0.config(state=tk.ACTIVE)
    #...

EDIT

This doesn't work on Mac OSx apparently. This link shows how in should look: http://www.tutorialspoint.com/python/tk_relief.htm

Solution 2

If Tkinter.Button doesn't allow to configure its relief property on your system then you could try ttk.Button-based code instead:

try:
    import Tkinter as tk
    import ttk
except ImportError: # Python 3
    import tkinter as tk
    import tkinter.ttk as ttk

SUNKABLE_BUTTON = 'SunkableButton.TButton'

root = tk.Tk()
root.geometry("400x300")
style = ttk.Style()

def start():
    button.state(['pressed', 'disabled'])
    style.configure(SUNKABLE_BUTTON, relief=tk.SUNKEN, foreground='green')

def stop():
    button.state(['!pressed', '!disabled'])
    style.configure(SUNKABLE_BUTTON, relief=tk.RAISED, foreground='red')

button = ttk.Button(root, text ="Start", command=start, style=SUNKABLE_BUTTON)
button.pack(fill=tk.BOTH, expand=True)
ttk.Button(root, text="Stop", command=stop).pack(fill=tk.BOTH, expand=True)
root.mainloop()
Share:
15,127
Gianni Spear
Author by

Gianni Spear

Updated on July 07, 2022

Comments

  • Gianni Spear
    Gianni Spear almost 2 years

    I am trying to find a way Tkinter to make the Start button stay pressed until I press the Stop button.

    from Tkinter import *
    import tkMessageBox
    
    
    class MainWindow(Frame):
        def __init__(self):
            Frame.__init__(self)
            self.master.title("input")
            self.master.minsize(250, 150)
            self.grid(sticky=E+W+N+S)
    
            top=self.winfo_toplevel()
            top.rowconfigure(0, weight=1)
            top.columnconfigure(0, weight=1)
    
            for i in range(2):self.rowconfigure(i, weight=1)
            self.columnconfigure(1, weight=1)
    
            self.button0 = Button(self, text="Start", command=self.save, activeforeground="red")
            self.button0.grid(row=0, column=0, columnspan=2, pady=2, padx=2, sticky=E+W+N+S)
    
            self.button1 = Button(self, text="Stop", command=self.stop, activeforeground="red")
            self.button1.grid(row=1, column=0, columnspan=2, pady=2, padx=2, sticky=E+W+N+S)
    
        def save(self):
            pass
    
        def stop(self):
            pass
    
    
    if __name__=="__main__":
       d=MainWindow()
       d.mainloop()
    
  • ebarr
    ebarr about 10 years
    Which part doesn't work? I think there may be a platform dependance here, as this works on my Linux box, but not on Mac OSx.
  • jfs
    jfs about 10 years
    "dosen't work" is not very informative. What happens? Do you see any errors? Here's a complete code example to try
  • ebarr
    ebarr about 10 years
    @J.F.Sebastian It would appear that on MacOSx (at least on 10.7.5 with python 2.7) the button is never depressed and the relief state cannot be set.
  • jfs
    jfs about 10 years
    does it fail with both .config and .configure methods? I've updated the gist
  • ebarr
    ebarr about 10 years
    @J.F.Sebastian Yes. The state of the button can be set without any problems (an the same goes for hover colours, backgrounds etc.) but the relief appears to be fixed in a raised state.
  • jfs
    jfs about 10 years
    I've added ttk-based variant.
  • ebarr
    ebarr about 10 years
    @J.F.Sebastian Still no, it alters the highlight colour and the text colour, but not the relief.
  • jfs
    jfs about 10 years
  • ebarr
    ebarr about 10 years
    @J.F.Sebastian again no. I suspect there is no straight forward way to do this given the way buttons are rendered on Mac.