Reputation: 101
I am trying to create buttons that delete themselves. In the code below, I create some amount of buttons in a for loop, append them to a list, and grid them. I am able to delete and remove any button in a certain index position of the buttons list, but need to figure out how to make each button locate itself in the buttons list.
from tkinter import *
import random
class App(Tk):
def __init__(self):
Tk.__init__(self)
self.totalButtons = random.randint(5, 25)
# The buttons will be stored in a list
self.buttons = []
self.labels = []
self.createButtons()
def createButtons(self):
for i in range(0, self.totalButtons):
# Here I create a button and append it to the buttons list
self.buttons.append(Button(self, text = i, command = self.removeButton))
# Now I grid the last object created (the one we just created)
self.buttons[-1].grid(row = i + 1, column = 1)
# Same thing for the label
self.labels.append(Label(self, text = i))
self.labels[-1].grid(row = i + 1, column = 0)
def removeButton(self):
# When a button is clicked, buttonIndex should be able to find the index position of that button in self.buttons
# For now I set it to 0, which will always remove the first (top) button
indexPosition = 0
# Takes the button (in this case, the first one) off the grid
self.buttons[indexPosition].grid_forget()
# Removes that button from self.buttons
del self.buttons[indexPosition]
# Same for the label
self.labels[indexPosition].grid_forget()
del self.labels[indexPosition]
def main():
a = App()
a.mainloop()
if __name__ == "__main__":
main()
Thanks!
Upvotes: 2
Views: 426
Reputation: 5384
command = lambda idx=i: self.removeButton(idx)
lambda here is taking the value i
from your range and assigning it to idx
and passing into the function. This function call is now unique to each button and so they have a value corresponding to their index.
for i, btn in enumerate(self.buttons):
btn['command'] = lambda idx=i: self.removeButton(idx)
Because you are deleting each button from the list you need to assign a new value to the command parameter to properly reflect where the new position of the existing buttons in the list are.
def createButtons(self):
for i in range(0, self.totalButtons):
# Here I create a button and append it to the buttons list
self.buttons.append(Button(self, text = i, command = lambda idx=i: self.removeButton(idx)))
# Now I grid the last object created (the one we just created)
self.buttons[-1].grid(row = i + 1, column = 1)
# Same thing for the label
self.labels.append(Label(self, text = i))
self.labels[-1].grid(row = i + 1, column = 0)
def removeButton(self, i):
# Takes the button at index i off the grid
self.buttons[i].grid_forget()
# Removes that button from self.buttons
del self.buttons[i]
# Same for the label
self.labels[i].grid_forget()
del self.labels[i]
# Assign new values for index position
for new_i, btn in enumerate(self.buttons):
btn['command'] = lambda idx=new_i: self.removeButton(idx)
Upvotes: 2