1

I am working on my pet-project. Under the working on GUI part, I faced a problem. I want to add a new widget after clicking the checkbox the first time, and on the second click, this widget should be removed. But in reality, I hav a problem with that. My new widget has been added but not removed. Could you please find the solution yo this issue?

It is my minimum reproducible part of code. The class Window, in initializing, creates TK object as a self.root var and creates a checkbox cb on that. That checkbox has a command self.create_or_delete_new_field, which depends on the status of cb_var, which is Checkbox variable. If cb_var is True, new labek lbl is created on self.root, if False - is deleted.

import tkinter as tk
class Window:
 def __init__(self):
 # pre-setups window
 self.root = tk.Tk()
 # checkbox
 cb_var = tk.BooleanVar()
 cb_var.set(0)
 cb = tk.Checkbutton(self.root, text="Checkbox1", onvalue=True, offvalue=False, variable=cb_var,
 command=lambda: self.create_or_delete_new_field(cb_var))
 cb.grid(row=0, column=0)
 self.root.mainloop()
 def create_or_delete_new_field(self, cb_var: bool):
 lbl = tk.Label(self.root, text=f" Created Label")
 if cb_var.get():
 lbl.grid(row=0, column=1, sticky='w')
 else:
 lbl.grid_remove()
app = Window()

I tried not only grid_remove() method but also grid_forget(), destroy(). As I can see the root of problem is deeper than that methods, but my experience cannot find that.

asked Jun 13, 2024 at 13:04
1
  • 1
    Every time you call create_or_delete_new_field(), you create a brand-new Label - and then either make it visible, or leave it invisible. You NEVER do anything with a previous Label, because that value of lbl vanished as soon as the function exited. You need for lbl to be something persistent - an attribute of your class, or a global variable. Commented Jun 13, 2024 at 13:16

2 Answers 2

3

Here's a working example. The idea here is to instantiate the Label during Window.__init__() so you're only creating a single label. I've also used Window as the root by inheriting from tk.Tk, since that's common practice. The other trick is using self appropriately to allow the toggle_widget method to access both cb_var and lbl

import tkinter as tk
class Window(tk.Tk):
 def __init__(self) -> None:
 super().__init__()
 self.geometry('400x400')
 self.title('Window')
 self.cb_var = tk.BooleanVar(self, False) # you can set the initial value here
 # NOTE: specifying on/off values isn't strictly necessary
 self.cb = tk.Checkbutton(
 self,
 text='Checkbox1',
 variable=self.cb_var,
 command=self.toggle_widget,
 )
 self.cb.grid(row=0, column=0)
 self.lbl = tk.Label(self, text='Hello!')
 def toggle_widget(self) -> None:
 if self.cb_var.get():
 self.lbl.grid(row=0, column=1, sticky='w')
 else:
 self.lbl.grid_forget()
if __name__ == '__main__':
 app = Window()
 app.mainloop()
answered Jun 13, 2024 at 13:16
Sign up to request clarification or add additional context in comments.

2 Comments

thank you so much, your example is really helpful!
Glad I could help. If this answer worked for you, please mark it as "accepted" with the checkmark button so that others know this question has been answered.
0

Explanation given as comments

import tkinter as tk
class Window(tk.Tk): #make root as argument
 def __init__(self):
 
 #Add this line
 super().__init__()
 self.geometry('200x100')
 self.title('Window')
 
 # No need of declaring boolen_variable as we create 2 functions
 # Declare self.lbl here and don't pack (or don't add grid)
 #There is no need of using f-string
 self.lbl = tk.Label(self, text= "Created Label") 
 
 self.cb = tk.Checkbutton(self, text="Create Label", command=self.create_lbl)
 self.cb.grid(row=0, column=0)
 
 def create_lbl(self):
 
 # pack the lbl here
 self.lbl.grid(row=1, column=0, sticky='w')
 
 # Change the text of check button as 'Hide label' 
 self.cb.configure(text = 'Hide_Label', command = self.hide_lbl)
 
 def hide_lbl(self):
 
 # Use grid_forget to hide label
 self.lbl.grid_forget()
 
 # Change the text of check button as 'Create label'
 self.cb.configure(text = 'Create Label', command = self.create_lbl)
 
 
if __name__ == '__main__':
 app = Window()
 app.mainloop() 
answered Jun 14, 2024 at 2:38

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.