¿Cómo obtener el estado de múltiples Botones de verificación en Tkinter?

Estoy escribiendo un pequeño progtwig Tkinter / Python, que tiene una lista de casillas de verificación con longitud variable (determinada en el tiempo de ejecución).

Quiero poder leer el estado de todas las casillas de verificación en cualquier momento, pero no estoy seguro de cómo debo hacerlo.

Aquí está el fragmento de código para generar la lista (adoptado de esta publicación ):

def relist(self): self.text.delete(1.0,END) p = subprocess.Popen (['ls', '/dev/'], stdout = subprocess.PIPE) lst = p.communicate()[0].split('\n') print lst for item in lst: v = tk.IntVar() cb = tk.Checkbutton(text="/dev/%s" % item, variable=v, command=self.cb(index)) self.text.window_create("end", window=cb) self.text.insert("end", "\n") # to force one checkbox per line 

Y mi maniquí

 def cb(self,idx): print ("var is %s", str(idx)) lst[idx] = 1; 

El problema es que a mi controlador se le llama una vez (cuando se crean los Botones de verificación), mientras que quiero que se llame cada vez que se hace clic (se Checkbutton o no) un Checkbutton verificación, y cuando se llama, quiero que se actualice primero.

    Tu comando CheckButton está ejecutando la callback porque eso es lo que le estás diciendo que haga. Se supone que el comando es una referencia a una función que tkinter puede ejecutar cuando se hace clic en el botón de verificación. Tkinter pasa el objeto de evento a la función de callback. Vea este tutorial de Effbot , pero parece que ya está intentando implementar su patrón. Puede obtener una referencia al botón de verificación del atributo event.widget como se explica aquí . Finalmente, debe adjuntar su variable a “self” si desea referirse a ella en la callback.

     def relist(self): self.text.delete(1.0,END) p = subprocess.Popen (['ls', '/dev/'], stdout = subprocess.PIPE) lst = p.communicate()[0].split('\n') print lst self.var = tk.IntVar() for item in lst: cb = tk.Checkbutton(text="/dev/%s" % item, variable=self.var, command=self.myCallback) self.text.window_create("end", window=cb) self.text.insert("end", "\n") # to force one checkbox per line def myCallback(self,event): var = self.var.get() print ("var is %s", str(var)) 

    Creo que lo que has pedido se puede derivar de aquí .

    Para cada item in lst , debe crearse previamente una variable IntVar() diferente, solo para indicar el estado independiente de cada checkbox. No veo otra forma que crearlos manualmente (supongo que no tiene cientos de casillas de verificación). Reutilizaré el código de esta respuesta y haré lo siguiente:

     def relist(self): self.text.delete(1.0,END) p = subprocess.Popen (['ls', '/dev/'], stdout = subprocess.PIPE) lst = p.communicate()[0].split('\n') print lst self.var1 = tk.IntVar() self.var2 = tk.IntVar() self.var3 = tk.IntVar() . . . vars = [self.var1,self.var2,self.var3,...] for item, var in zip(self.lst, vars): cb = tk.Checkbutton(text="/dev/%s" % item, variable=var, command= lambda: self.myCallback(var)) self.text.window_create("end", window=cb) self.text.insert("end", "\n") # to force one checkbox per line def myCallback(self,event,var): each_var = var.get() print ("var is %s", str(each_var)) 

    Tuve el mismo problema. Prueba este:

     cb = tk.Checkbutton(text="/dev/%s" % item, variable=v, command=lambda: self.cb(index)) 

    Si pasa el método como función lambda, ejecuta el método en cada cambio de la variable.

    Personalmente no uso un tk.IntVar () / tk.StringVar () etc. pero tal vez debería. Puede que no sea la mejor manera de hacerlo, pero creo que es bastante fácil de entender. no dude en criticar y decirme lo que es realmente malo y no pythonic para que pueda mejorar (todavía soy un novato).

    hago un interator y luego creo mis botones de control en un bucle y en la callback paso en el parámetro el valor del botón de control y el iterador.

      ... self.listeColonneFile1 = [] self.chbFile1 = [] indice = 0 for column in dfFile1.columns: btn = ttk.Checkbutton(self.frameCheckButtonsFile1, text=column, command=lambda i=indice, col=column: self.callback_onCheck(col, i) ) self.chbFile1.append(btn) self.chbFile1[indice].grid(row = indice, column = 0, sticky="nw") self.chbFile1[indice].state(['!alternate']) indice += 1 

    En mi callback, tengo una lista de todos los checkButtons que están marcados (bueno, no el ChB sino su texto o su valor):

     def callback_onCheck(self, column, indice): if self.chbFile1[indice].instate(['selected']) == True: self.listeColonneFile1.append(column) else: self.listeColonneFile1.remove(column) 

    PS: dfFile1 es un DataFrame de pandas, vea el documento