'How to disable an Entry on tkinter when a Checkbutton is unchecked using for loop and dictionary

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



Solution 1:[1]

As per my understanding. you are asking to link check button and Line Edit. i given example code to link.

import tkinter
from tkinter import *

def test():
    if e['state'] == 'normal':
        e['state'] = 'disabled'
    else:
        e['state'] = 'normal'

w=Tk()
e=Entry()
e.pack()
cb=Checkbutton(command=test)
cb.select()
cb.pack()
w.mainloop()

Solution 2:[2]

Update:

As @acw1668 said, I used self.cur_entry to change the entry's state when checkbutton is checked or unchecked and this only change the last entry's state. I created instead a list and appended the entries created to it :

from tkinter import *

class Principal():
    
    def __init__(self):
        
        self.root= Tk()

        self.root.geometry('800x800') 
        
        self.AjouterArticleFrame = LabelFrame(self.root, text="Ajouter un article", width=2000)
        self.AjouterArticleFrame.place_forget()

        self.DefautArticlesCheckButton={
            "Deblai" : IntVar(value=1),
            "Remblai" : IntVar(value=1),
            "Blocage" : IntVar(value=1),
            "Beton de propreté": IntVar(value=1),
            "Beton armé": IntVar(value=1),
            "Acier à haute adherence": IntVar(value=1),
            "Joint de dilatation": IntVar(value=1),
            }
        
        self.variablesList=[]
        for index, (key, value) in enumerate(self.DefautArticlesCheckButton.items()):
            checkbutton_=Checkbutton(self.prixArticlesFrame, text=key,variable=self.DefautArticlesCheckButton[key], onvalue=1, offvalue=0,command=self.DefaultArticlesEntryState)
            checkbutton_.grid(row=index, column=0, padx=10, pady=10, sticky="W")
            self.variablesList.append(self.DefautArticlesCheckButton[key])

        
        self.DefautArticlesPrix=[
            "Deblai" ,
            "Remblai" ,
            "Blocage" ,
            "Beton de propreté" ,
            "Beton armé" ,
            "Acier à haute adherence" ,
            "Joint de dilatation",
        ]
        self.DefautArticlesPrixEntriesWidgets=[]


        for i in self.DefautArticlesPrix:
            entry_prix=Entry(self.prixArticlesFrame,width=10)
            entry_prix.grid(row=self.DefautArticlesPrix.index(i),column=2,padx=10)
            self.DefautArticlesPrixEntriesWidgets.append(entry_prix)


    def DefaultArticlesEntryState(self):
        for i in range(len(self.variablesList)):
            if int(self.variablesList[i].get()) == 1:
                self.DefautArticlesPrixEntriesWidgets[i].grid(row=i,column=2,padx=10)
                self.DefautArticlesPrixEntriesWidgets[i].config(state=NORMAL)

            elif int(self.variablesList[i].get()) == 0:
                self.DefautArticlesPrixEntriesWidgets[i].config(state=DISABLED) 

app = Principal()
             
        
      

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Viswa
Solution 2