Foro de elhacker.net

Programación => Scripting => Mensaje iniciado por: Yidu en 9 Julio 2017, 18:21 pm



Título: ¿Se puede simplificar el código del Checkbutton en tkinter? [SOLUCIONADO] :)
Publicado por: Yidu en 9 Julio 2017, 18:21 pm
Hola de nuevo!  :D

Llevo un tiempo haciendo programas de Python en consola. Ahora me he decidido por usar una GUI. Y me he decantado por tkinter. He ido conociendo un poco los widgets y con el Checkbutton me han asaltado unas dudas:

En casi todos los ejemplos se crean unos pocos Checkbutton. Para cada uno de ellos se debe crear la variable de su estado y una función (normalmante llamada por command del widget Button). Pero claro, si queremos crear, por ejemplo, diez o veinte Checkbutton la cosa se desmadra y se crea un código redundante y repetitivo.

Ejemplo:

Código
  1. def imprime():
  2.    global lista
  3.    lista = []
  4.    if _1.get() == 1:
  5.        lista.append(1)
  6.    if _2.get() == 1:
  7.        lista.append(2)
  8.    if _3.get() == 1:
  9.        lista.append(3)
  10.    if _4.get() == 1:
  11.        lista.append(4)
  12.    if _5.get() == 1:
  13.        lista.append(5)
  14.    if _6.get() == 1:
  15.        lista.append(6)
  16.    if _7.get() == 1:
  17.        lista.append(7)
  18.    if _8.get() == 1:
  19.        lista.append(8)
  20.    if _9.get() == 1:
  21.        lista.append(9)
  22.    if _10.get() == 1:
  23.        lista.append(10)
  24. _1 = IntVar()
  25. _2 = IntVar()
  26. _3 = IntVar()
  27. _4 = IntVar()
  28. _5 = IntVar()
  29. _6 = IntVar()
  30. _7 = IntVar()
  31. _8 = IntVar()
  32. _9 = IntVar()
  33. _10 = IntVar()
  34. chk1 = Checkbutton(ventana, text = '1', variable = _1, onvalue = 1, offvalue = 0).place(x = 10, y = 30)
  35. chk2 = Checkbutton(ventana, text = '2', variable = _2, onvalue = 1, offvalue = 0).place(x = 10, y = 60)
  36. chk3 = Checkbutton(ventana, text = '3', variable = _3, onvalue = 1, offvalue = 0).place(x = 10, y = 90)
  37. chk4 = Checkbutton(ventana, text = '4', variable = _4, onvalue = 1, offvalue = 0).place(x = 10, y = 120)
  38. chk5 = Checkbutton(ventana, text = '5', variable = _5, onvalue = 1, offvalue = 0).place(x = 10, y = 150)
  39. chk6 = Checkbutton(ventana, text = '6', variable = _6, onvalue = 1, offvalue = 0).place(x = 10, y = 180)
  40. chk7 = Checkbutton(ventana, text = '7', variable = _7, onvalue = 1, offvalue = 0).place(x = 10, y = 210)
  41. chk8 = Checkbutton(ventana, text = '8', variable = _8, onvalue = 1, offvalue = 0).place(x = 10, y = 240)
  42. chk9 = Checkbutton(ventana, text = '9', variable = _9, onvalue = 1, offvalue = 0).place(x = 10, y = 270)
  43. chk10 = Checkbutton(ventana, text = '10', variable = _10, onvalue = 1, offvalue = 0).place(x = 60, y = 30)


Esto es un extracto del código. El que hace referencia a la duda que me surge. Es decir, se puede dar el caso que un programa tenga 100 casillas a seleccionar ¿Cómo se puede evitar este código tan repetitivo?

Saludos!


Título: Re: ¿Se puede simplificar el código del Checkbutton en tkinter? [PYTHON]
Publicado por: engel lex en 9 Julio 2017, 20:16 pm
no se porque tienes variables _1, _2 en lugar de usar un array

mi solución sería (asumiendo que en lugar _1, _2 tienes un array con sus elementos
Código
  1.  
  2. def imprime(elementos):
  3. lista = []
  4. maximo_y = 9
  5. chk = []
  6. for i in range(len(elementos)):
  7.  if elementos[i].get() == 1:
  8.   lista.append(i+1)  
  9.  elementos[i] = IntVar()
  10. chk.append( Checkbutton(ventana, text = str(i), variable = elementos[i], onvalue = 1, offvalue = 0).place(x = int(i/maximo_y)*50+10, y = (i%maximo_y)*30+30) )
  11.  

lo estoy haciendo a mente, así que revisa, pero la logica debería estar bien, creo


Título: Re: ¿Se puede simplificar el código del Checkbutton en tkinter? [PYTHON]
Publicado por: Yidu en 10 Julio 2017, 19:03 pm
Muchas gracias por el script  :D

Me imaginaba, que no era lógico, poner tantos IFs y líneas repetitivas. Vi unos ejemplos donde su autor explicaba, de alguna manera, el Checkbutton. Claro esta que en su ejemplo eran solo tres Checkbutton. Pero claro, si uno debe poner cien (por ejemplo), tarde o temprano se las tiene que ingeniar con un algoritmo como el tuyo. Le echado un vistazo por encima y creo que debe estar bien. Eso sin contar que luego recomiendan usar la OOP para usar tkinter.

Para familiarizarme con tkinter estaba creando un simple escrutador de loteria primitiva. Aquí una captura:

(http://i66.tinypic.com/v8ekww.png)

Al final, el tema de la ubicación de los Checkbutton lo he solucionado en el siguiente script. Seguramente tu método será mejor. Pero a mi me gusta (aunque sean mas lineas) que el código no quede tan compacto.  Lo digo en referencia del método place().

Código
  1. # Creacion de los Checkbutton
  2. varsCheck =[]
  3. coord_x, coord_y = 10, 60 # Coordenadas iniciales
  4. for i in range(0, 49):
  5.    varsCheck.append(IntVar())      
  6.    Checkbutton(ventana, text = str(i + 1), variable = varsCheck[i], onvalue = 1, offvalue = 0).place(x = coord_x, y = coord_y)    
  7.    coord_y += 30  
  8.    if coord_y > 300:
  9.        coord_y = 30
  10.        coord_x += 50