Home > Net >  Disabling all buttons when one is clicked
Disabling all buttons when one is clicked

Time:12-05

I have multiple buttons in tkinter and I want to disable all of them after any one of them is clicked once.

from tkinter import *
root = Tk()
Button1 = Button(root)
Button1['state'] = DISABLED
Button2 = Button(root)
Button2['state'] = DISABLED
Button3 = Button(root)
Button3['state'] = DISABLED
Button4 = Button(root)
Button4['state'] = DISABLED
Button1.grid(row = 5, column = 1, rowspan = 2)
Button2.grid(row = 5, column = 2, rowspan = 2)
Button3.grid(row = 5, column = 3, rowspan = 2)
Button4.grid(row = 5, column = 4, rowspan = 2)
root.mainloop()

Each button has a command function that removes that button from an external list of buttons, so i tried a while loop, hoping that it will keep the button state normal until one is clicked and therefore removed from the list and therefore the list gets shorter for that one button and the while loop ends, however this results in en endless loop where the buttons remain disabled instead of normal. I dont understand how the loop is spinning without making any buttons enabled again.

                while len(list) == 4:
                    Button1['state'] = NORMAL
                    Button2['state'] = NORMAL
                    Button3['state'] = NORMAL
                    Button4['state'] = NORMAL    
                Button1['state'] = DISABLED
                Button2['state'] = DISABLED
                Button3['state'] = DISABLED
                Button4['state'] = DISABLED    
              

I also tried this with the same result:

                Button1['state'] = NORMAL
                Button2['state'] = NORMAL
                Button3['state'] = NORMAL
                Button4['state'] = NORMAL  
                while True:  
                  if len(list) == 3:
                     Button1['state'] = DISABLED
                     Button2['state'] = DISABLED
                     Button3['state'] = DISABLED
                     Button4['state'] = DISABLED
                     break

CodePudding user response:

from tkinter import *
root = Tk()
root.geometry("500x400")

def do_somthing():
   print("Ypu pressed Button and Disabled All Buttons")

def disable_button():
   buttons = [Button1 ,Button2 ,Button3 ,Button4]
   for button in buttons :
      button.config(state="disabled")
   do_somthing()

Button1 = Button(root ,text="Button 1" ,command= disable_button)
Button1.pack()
Button2 = Button(root ,text="Button 2"  ,command= disable_button)
Button2.pack()
Button3 = Button(root ,text="Button 3"  ,command= disable_button)
Button3.pack()
Button4 = Button(root ,text="Button 4"  ,command= disable_button)
Button4.pack()
root.mainloop()

CodePudding user response:

I'm not sure I really understand what you are asking for. The following code might be doing all you need.

The buttons are disabled until do_other_things is done and allows remove_button to enable all buttons again. This does not stop you from clicking the buttons and remove the next one. But this process will only start after the button already clicked is done with its work.

remove_button removes the button from root and also from the buttons list so you can clicking buttons until all are gone.

You might notice the partial in the button command. If you use a lambda at this point only the last button will be bind correctly, that why you need to use partial

import time
import tkinter
from functools import partial

root = tkinter.Tk()
root.geometry("500x400")


def button_click(button):
    disable_all_buttons()
    root.after(1, lambda: remove_button(button)) # waits 1 milisecond to execute remove_button so the gui can update


def remove_button(button):
    index = buttons.index(button)
    buttons[index].destroy()
    buttons.remove(button)
    do_other_things()  # simulates workload
    enable_all_buttons()  # when all is done, the buttons are set back to normal


def disable_all_buttons():
    for button in buttons:
        button.config(state=tkinter.DISABLED)


def enable_all_buttons():
    for button in buttons:
        button.config(state=tkinter.NORMAL)


def do_other_things():
    time.sleep(1)  # simulate code that delays further execution for 1 second


button_names = ['Button 1', 'Button 2', 'Button 3', 'Button 4', 'Button 5']
buttons = []
for button in button_names:
    widget = tkinter.Button(root, text=button)
    widget.config(command=partial(button_click, widget))
    widget.pack()
    buttons.append(widget)

root.mainloop()
  • Related