3 votes

Pourquoi ces boutons de contrôle Python tkinter sont-ils liés ?

J'essaie actuellement de créer une interface graphique pour comparer des fichiers entre deux dossiers différents et j'ai un cadre rudimentaire sur lequel j'essaie de m'appuyer pour l'instant.

J'ai trois cadres à gauche, à droite et en bas de la fenêtre avec deux boutons de contrôle chacun. Je souhaite pouvoir sélectionner chaque bouton indépendamment les uns des autres, mais chaque fois que je clique sur le premier bouton de l'un des cadres, le premier bouton des autres cadres se sélectionne/désélectionne en même temps.

Pourquoi en est-il ainsi et comment les faire fonctionner indépendamment l'un de l'autre ? Voici mon code pour référence :

from tkinter import *

root = Tk()

leftFrame = Frame(root, bg = "#4d94ff")
leftFrame.pack(side = LEFT, fill = BOTH)

rightFrame = Frame(root, bg = "#ff4d4d")
rightFrame.pack(side = RIGHT, fill = BOTH)

bottomFrame = Frame(root, bg = "#5cd65c")
bottomFrame.pack(side = BOTTOM)

check_L1 = Checkbutton(leftFrame, text = "C1", bg = "#4d94ff")
check_L2 = Checkbutton(leftFrame, text = "C2", bg = "#4d94ff")

check_R1 = Checkbutton(rightFrame, text = "C1", bg = "#ff4d4d")
check_R2 = Checkbutton(rightFrame, text = "C2", bg = "#ff4d4d")

checktype1 = Checkbutton(bottomFrame, text = "Check Type 1", bg = "#5cd65c")
checktype2 = Checkbutton(bottomFrame, text = "Check Type 2", bg = "#5cd65c")

check_L1.grid(row = 0)
check_L2.grid(row = 0, column = 1)
check_R1.grid(row = 0)
check_R2.grid(row = 0, column = 1)
checktype1.grid(row = 0)
checktype2.grid(row = 1)

root.mainloop()

4voto

Bryan Oakley Points 63365

TL;DR

Vous devez spécifier un variable avec chaque bouton de contrôle.

var_L1 = tk.IntVar()
var_R1 = tk.IntVar()
...
check_L1 = Checkbutton(..., variable=var_L1)
check_R1 = Checkbutton(..., variable=var_R1)
...

Ce qui se passe

Les boutons de contrôle doivent être associés à une variable. Comme vous ne définissez pas explicitement de variable, Tkinter crée des valeurs par défaut. Pour ce faire, Tkinter crée des variables internes nommées d'après le nom du bouton de contrôle.

Lorsque vous créez des widgets et que vous ne leur donnez pas de nom, tkinter choisit des noms par défaut. Le nom complet comprend les noms de toute la hiérarchie des widgets. Ainsi, par exemple, le nom interne de check_L1 es .!frame.!checkbutton' , le nom de check_R1 es .!frame2.!checkbutton et la dénomination interne de checktype1 es '.!frame3.!checkbutton' .

Lorsque tkinter crée les variables par défaut pour les boutons de contrôle, il n'utilise que la dernière composante du nom complet pour les variables. Ainsi, pour check_L1 il crée une variable interne nommée !checkbutton . La variable interne pour check_R1 est également !checkbutton de même que la variable interne pour checktype2 .

Comme tous ces boutons de contrôle partagent la même variable interne, ils sont liés.


Remarque : si vous créez un grand nombre de cases à cocher dans une boucle, vous pouvez enregistrer la référence de chaque bouton dans un tableau. Par exemple, vous pouvez enregistrer la référence de chaque bouton de contrôle dans un tableau :

vars = []
for i in range(x):
    vars.append[tk.IntVar())
...
check_L1 = Checkbutton(..., variable=vars[0])
...
print(f"the value of L1 is {vars[0].get()}")

1voto

MaxiMouse Points 2671

Je ne sais pas exactement pourquoi cela se produit, mais vous pouvez rendre les boutons de contrôle indépendants en les associant à une variable :

from tkinter import *

root = Tk()

leftFrame = Frame(root, bg = "#4d94ff")
leftFrame.pack(side = LEFT, fill = BOTH)

rightFrame = Frame(root, bg = "#ff4d4d")
rightFrame.pack(side = RIGHT, fill = BOTH)

bottomFrame = Frame(root, bg = "#5cd65c")
bottomFrame.pack(side = BOTTOM)

check_L1 = Checkbutton(leftFrame, text = "C1", bg = "#4d94ff", variable=IntVar())
check_L2 = Checkbutton(leftFrame, text = "C2", bg = "#4d94ff", variable=IntVar())

check_R1 = Checkbutton(rightFrame, text = "C1", bg = "#ff4d4d", variable=IntVar())
check_R2 = Checkbutton(rightFrame, text = "C2", bg = "#ff4d4d", variable=IntVar())

checktype1 = Checkbutton(bottomFrame, text = "Check Type 1", bg = "#5cd65c", variable=IntVar())
checktype2 = Checkbutton(bottomFrame, text = "Check Type 2", bg = "#5cd65c", variable=IntVar())

check_L1.grid(row = 0)
check_L2.grid(row = 0, column = 1)
check_R1.grid(row = 0)
check_R2.grid(row = 0, column = 1)
checktype1.grid(row = 0)
checktype2.grid(row = 1)

root.mainloop()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X