I'm working on a Windows application for my work and my knowledge on Python is very limited, so I didn't know how to figure this out :
I want to make each entry widget inside the frame disabled when its checkbutton is unchecked and enabled when its checkbutton is checked and make them all checked by default. I tried this code that I took part of it from this tutorial but it didn't work as expected.
from tkinter import *
class Principal():
def __init__(self):
self.root= Tk()
self.root.geometry('800x800')
self.prixArticlesFrame = LabelFrame(self.root, text="Prix des articles", width=2000)
self.prixArticlesFrame.place(relx = 0.75, rely = 0.15,anchor = N)
self.DefautArticlesCheckButton={
"Deblai" : IntVar(),
"Remblai" : IntVar(),
"Blocage" : IntVar(),
"Beton de propreté": IntVar(),
"Beton armé": IntVar(),
"Acier à haute adherence": IntVar(),
"Joint de dilatation": IntVar(),
}
for index, (key, value) in enumerate(self.DefautArticlesCheckButton.items()):
self.cur_check = Checkbutton(self.prixArticlesFrame,
text=key,variable=self.DefautArticlesCheckButton[key], onvalue=1,
offvalue=0,command=self.ArticlesEntryState)
self.cur_check.grid(row=index, column=0, padx=10, pady=10, sticky="W")
self.DefautArticlesEntries={
"Deblai" : StringVar(),
"Remblai" : StringVar(),
"Blocage" : StringVar(),
"Beton de propreté": StringVar(),
"Beton armé": StringVar(),
"Acier à haute adherence": StringVar(),
"Joint de dilatation": StringVar(),
}
for index, (key, value) in enumerate(self.DefautArticlesEntries.items()):
self.cur_entry = 'DefautArticlesEntries' +key
self.cur_entry=Entry(self.prixArticlesFrame,width=10,
textvariable=self.DefautArticlesEntries[key])
self.cur_entry.grid(row=index,column=2,padx=10)
self.cur_entry.config(state=NORMAL)
self.root.mainloop()
def ArticlesEntryState(self):
for index, (key, value) in enumerate(self.DefautArticlesCheckButton.items()):
if self.DefautArticlesCheckButton[key].get() == 1:
self.cur_entry.grid(row=index,column=2,padx=10)
self.cur_entry.config(state=NORMAL)
elif self.DefautArticlesCheckButton[key].get() == 0:
self.cur_entry.config(state=DISABLED)
app = Principal()
here is what I got in gif image
What I have done wrong? Thanks
Since you want all buttons checked by default, all variables should have an initial value that matches their onvalue
.
Besides, both dicts refer to the variables rather than the actual widgets, so each Entry
must be bound to the scope of the corresponding IntVar
trace callback - otherwise, only the last loop item is referenced:
for index, (key, value) in enumerate(self.DefautArticlesCheckButton.items()):
value.set(1)
check = Checkbutton(self.prixArticlesFrame, text=key, variable=value)
check.grid(row=index, column=0, padx=10, pady=10, sticky="W")
# ...
for index, (key, value) in enumerate(self.DefautArticlesEntries.items()):
entry = Entry(self.prixArticlesFrame, width=10, textvariable=value)
entry.grid(row=index, column=1, padx=10)
var = self.DefautArticlesCheckButton[key]
handler = lambda *_, e=entry, v=var: e.config(state=NORMAL if v.get() else DISABLED)
var.trace('w', handler)