Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Modificación de widgets pestaña seleccionada
#1
Buenas:

Os pongo aquí un código simple para que veáis dónde puede estar el problema. (He intentado que fuera corto pero es que si no no hay manera de explicarlo bien).

  1. import tkinter as tk
  2. from tkinter import ttk
  3. from datetime import *
  4. from tkinter import messagebox
  5. import time
  6. import calendar
  7. import psycopg2
  8. import threading
  9. from threading import Timer
  10. import os
  11. import sys
  12.  
  13.  
  14.  
  15. class Prueba:
  16.  
  17. def __init__(self):
  18.  
  19. self.principal = tk.Tk()
  20. self.principal.title("Prueba NOTEBOOK")
  21. self.principal.geometry('600x600')
  22.  
  23. # FUNTIONS
  24.  
  25. def addcliente():
  26.  
  27. self.pest2 = ttk.Frame(self.note)
  28. self.note.add(self.pest2, text='CLIENTE')
  29.  
  30. # LABELS PESTAÑAS
  31.  
  32. self.lab = ttk.Label(self.pest2, text='NOMBRE')
  33. self.lab.grid(row=0, column=0)
  34.  
  35. self.lab1 = ttk.Label(self.pest2, text='APELLIDOS')
  36. self.lab1.grid(row=0, column=1)
  37.  
  38. self.lab2 = ttk.Label(self.pest2, text='EDAD')
  39. self.lab2.grid(row=0, column=2)
  40.  
  41. # ENTRYS PESTAÑAS
  42.  
  43. self.ent = ttk.Entry(self.pest2)
  44. self.ent.grid(row=1, column=0, padx=10)
  45.  
  46. self.ent1 = ttk.Entry(self.pest2)
  47. self.ent1.grid(row=1, column=1, padx=10)
  48.  
  49. # COMBOBOS PESTAÑAS
  50.  
  51. self.com = ttk.Combobox(self.pest2, width=3)
  52. self.com.grid(row=1, column=2, padx=10)
  53.  
  54. def valcliente():
  55.  
  56. self.ent.configure(state='disabled')
  57. self.ent1.configure(state='disabled')
  58.  
  59. def modcliente():
  60.  
  61. self.ent.configure(state='!disabled')
  62. self.ent1.configure(state='!disabled')
  63.  
  64.  
  65.  
  66.  
  67. # FRAMES
  68.  
  69. self.frame1 = ttk.Frame(self.principal)
  70. self.frame1.grid(row=0, column=0)
  71.  
  72. self.frame2 = ttk.Frame(self.principal)
  73. self.frame2.grid(row=1, column=0)
  74.  
  75. # NOTEBOOKS
  76.  
  77. self.note = ttk.Notebook(self.frame1, height=200)
  78. self.note.grid()
  79.  
  80. self.pest1 = ttk.Frame(self.note)
  81. self.note.add(self.pest1, text='CLIENTE')
  82.  
  83. # LABELS
  84.  
  85. self.lab = ttk.Label(self.pest1, text='NOMBRE')
  86. self.lab.grid(row=0, column=0)
  87.  
  88. self.lab1 = ttk.Label(self.pest1, text='APELLIDOS')
  89. self.lab1.grid(row=0, column=1)
  90.  
  91. self.lab2 = ttk.Label(self.pest1, text='EDAD')
  92. self.lab2.grid(row=0, column=2)
  93.  
  94. # ENTRYS
  95.  
  96. self.ent = ttk.Entry(self.pest1)
  97. self.ent.grid(row=1, column=0, padx=10)
  98.  
  99. self.ent1 = ttk.Entry(self.pest1)
  100. self.ent1.grid(row=1, column=1, padx=10)
  101.  
  102. # COMBOBOX
  103.  
  104. self.com = ttk.Combobox(self.pest1, width=3)
  105. self.com.grid(row=1, column=2, padx=10)
  106.  
  107. # BUTTONS
  108.  
  109. self.but = ttk.Button(self.frame2, text='Añadir', command=addcliente)
  110. self.but.grid(row=1, column=0, padx=5)
  111.  
  112. self.but1 = ttk.Button(self.frame2, text='Validar', command=valcliente)
  113. self.but1.grid(row=1, column=1, padx=5)
  114.  
  115. self.but2 = ttk.Button(self.frame2, text='Modificar', command= modcliente)
  116. self.but2.grid(row=1, column=2, padx=5)
  117.  
  118.  
  119.  
  120. self.principal.mainloop()
  121.  
  122.  
  123.  
  124.  
  125. def main():
  126. my_app = Prueba()
  127.  
  128. if __name__ == '__main__':
  129. main()


Bueno, la identación no funciona con un copia y pega desde Geany pero el código funciona.

Bien, en principio todo funciona correctamente. Se abre el notebook, y puedes poner el nombre y apellidos y una vez das al botón validar deshabilita  los ENTRYS para que no se borren por error. Si le das a modificar también funciona correctamente y vuelve a habilidar los ENTRYS para que realices modificaciones en el mismo.

El problema viene si añades más de una pestaña. Es decir abres la aplicación y en vez de poner nombre y apellidos en la primera pestaña añades otra directamente.(Botón añadir). Bien hasta aquí todo parece funcionar, pero si yo pulso el botón validar, la única pestaña que se valida es la última es decir la que has añadido y yo lo que quiero es que me haga la validación en la pestaña que tenga seleccionada). No importa qué pestaña tengas seleccionada, siempre realiza las "modificaciones" en la última que hayas añadido.

Muchas gracias de antemano.
Responder
#2
Hola. Cuando creás los widgets de la nueva pestaña en tu función addcliente(), a todos ellos les estás poniendo los mismos nombres que a los anteriores (self.ent, self.ent1, self.lab1, etc.); por ende, perdés la referencia de los anteriores y te quedás con los últimos controles creados. Por eso siempre tu código va a validar únicamente los datos de la última pestaña creada. Deberías tener una lista en la que vayas añadiendo los widgets que creás para no perder sus referencias.

Saludos
Responder
#3
(25-09-2019, 10:46 PM)Francisco escribió: Hola. Cuando creás los widgets de la nueva pestaña en tu función addcliente(), a todos ellos les estás poniendo los mismos nombres que a los anteriores (self.ent, self.ent1, self.lab1, etc.); por ende, perdés la referencia de los anteriores y te quedás con los últimos controles creados. Por eso siempre tu código va a validar únicamente los datos de la última pestaña creada. Deberías tener una lista en la que vayas añadiendo los widgets que creás para no perder sus referencias.

Saludos
MUCHAS GRACIAS.

Cómo me imaginaba era al igual que ya comentamos tema de listas. Una duda:

Me recomiendas hacer una única lista para todos los widgets es decir para todos los entrys por ejemplo o crear un lista para cada entry?.
Responder
#4
De nada Wink. Si son unos pocos controles no hay mucha diferencia entre una forma u otra. Mejor que eso sería crear una clase para abstraer las pestañas; podés ver cómo se hace en el último código de este artículo: https://recursospython.com/guias-y-manua...k-tkinter/.

Saludos!
Responder
#5
(26-09-2019, 03:29 PM)Francisco escribió: De nada Wink. Si son unos pocos controles no hay mucha diferencia entre una forma u otra. Mejor que eso sería crear una clase para abstraer las pestañas; podés ver cómo se hace en el último código de este artículo: https://recursospython.com/guias-y-manua...k-tkinter/.

Saludos!
MUCHAS GRACIAS. Si alguna vez veo finalizado este proyecto será gracias a ti.



Una duda: He visto el enlace que utilizas y cambia un poco las cosas lo de programar con clases.



¿Por qué este código no hace absolutamente nada?. Python no da ningún tipo de error pero tampoco representa nada de nada. (Al ejecutarlo se abre la consola sin errores pero nada más). Es como si no se inicializase ningúna de las clases.

  1. class Addpest():
  2.  
  3.  
  4.  
  5. def __init__(self):
  6.  
  7.  
  8. def addcliente():
  9.  
  10.  
  11.  
  12. self.pest2 = ttk.Frame(self.note)
  13.  
  14. self.note.add(self.pest2, text='CLIENTE')
  15.  
  16.  
  17.  
  18. # LABELS PESTAÑAS
  19.  
  20.  
  21.  
  22. self.lab = ttk.Label(self.pest2, text='NOMBRE')
  23. self.lab.grid(row=0, column=0)
  24.  
  25. self.lab1 = ttk.Label(self.pest2, text='APELLIDOS')
  26. self.lab1.grid(row=0, column=1)
  27.  
  28.  
  29.  
  30. self.lab2 = ttk.Label(self.pest2, text='EDAD')
  31.  
  32. self.lab2.grid(row=0, column=2)
  33.  
  34.  
  35.  
  36. # ENTRYS PESTAÑAS
  37.  
  38.  
  39.  
  40. self.ent = ttk.Entry(self.pest2)
  41.  
  42. self.ent.grid(row=1, column=0, padx=10)
  43.  
  44.  
  45.  
  46. self.ent1 = ttk.Entry(self.pest2)
  47.  
  48. self.ent1.grid(row=1, column=1, padx=10)
  49.  
  50.  
  51.  
  52. # COMBOBOS PESTAÑAS
  53.  
  54.  
  55.  
  56. self.com = ttk.Combobox(self.pest2, width=3)
  57.  
  58. self.com.grid(row=1, column=2, padx=10)
  59.  
  60.  
  61.  
  62.  
  63.  
  64. class Prueba():
  65.  
  66.  
  67.  
  68. def __init__(self):
  69.  
  70.  
  71.  
  72. self.principal = tk.Tk()
  73.  
  74. self.principal.title("Prueba NOTEBOOK")
  75.  
  76. self.principal.geometry('600x600')
  77.  
  78.  
  79.  
  80. def valcliente():
  81.  
  82.  
  83.  
  84. self.ent.configure(state='disabled')
  85.  
  86. self.ent1.configure(state='disabled')
  87.  
  88.  
  89.  
  90. def modcliente():
  91.  
  92.  
  93.  
  94. self.ent.configure(state='!disabled')
  95.  
  96. self.ent1.configure(state='!disabled')
  97.  
  98.  
  99.  
  100. # FRAMES
  101.  
  102.  
  103.  
  104. self.frame1 = ttk.Frame(self.principal)
  105.  
  106. self.frame1.grid(row=0, column=0)
  107.  
  108.  
  109.  
  110. self.frame2 = ttk.Frame(self.principal)
  111.  
  112. self.frame2.grid(row=1, column=0)
  113.  
  114.  
  115.  
  116. # NOTEBOOKS
  117.  
  118.  
  119.  
  120. self.note = ttk.Notebook(self.frame1, height=200)
  121.  
  122. self.note.grid()
  123.  
  124.  
  125.  
  126. self.pest1 = ttk.Frame(self.note)
  127.  
  128. self.note.add(self.pest1, text='CLIENTE')
  129.  
  130.  
  131.  
  132. # LABELS
  133.  
  134.  
  135.  
  136. self.lab = ttk.Label(self.pest1, text='NOMBRE')
  137.  
  138. self.lab.grid(row=0, column=0)
  139.  
  140.  
  141.  
  142. self.lab1 = ttk.Label(self.pest1, text='APELLIDOS')
  143.  
  144. self.lab1.grid(row=0, column=1)
  145.  
  146.  
  147.  
  148. self.lab2 = ttk.Label(self.pest1, text='EDAD')
  149.  
  150. self.lab2.grid(row=0, column=2)
  151.  
  152.  
  153.  
  154. # ENTRYS
  155.  
  156.  
  157.  
  158. self.ent = ttk.Entry(self.pest1)
  159.  
  160. self.ent.grid(row=1, column=0, padx=10)
  161.  
  162.  
  163.  
  164. self.ent1 = ttk.Entry(self.pest1)
  165.  
  166. self.ent1.grid(row=1, column=1, padx=10)
  167.  
  168.  
  169.  
  170. # COMBOBOX
  171.  
  172.  
  173.  
  174. self.com = ttk.Combobox(self.pest1, width=3)
  175.  
  176. self.com.grid(row=1, column=2, padx=10)
  177.  
  178.  
  179.  
  180. # BUTTONS
  181.  
  182.  
  183.  
  184. self.but = ttk.Button(self.frame2, text='Añadir', command=Addpest.addcliente)
  185.  
  186. self.but.grid(row=1, column=0, padx=5)
  187.  
  188.  
  189.  
  190. self.but1 = ttk.Button(self.frame2, text='Validar', command=valcliente)
  191.  
  192. self.but1.grid(row=1, column=1, padx=5)
  193.  
  194.  
  195.  
  196. self.but2 = ttk.Button(self.frame2, text='Modificar', command= modcliente)
  197.  
  198. self.but2.grid(row=1, column=2, padx=5)
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206. self.principal.mainloop()
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216. def main():
  217.  
  218. my_app = Prueba()
  219.  
  220.  
  221.  
  222. if __name__ == '__main__':
  223.  
  224. main()
Responder
#6
Es difícil determinarlo teniendo que reponer toda la sangría; intentá usando la opción de código genérico que provee el foro, por más que no aparezca el resaltado de sintaxis. No obstante no es necesario que te compliques con el tema de las clases, era solo una recomendación. Ya los conceptos de orientación a objetos son difíciles de asir y lleva su tiempo poder dominarlos. La idea de usar clases en una aplicación de Tk es la de tener distintas partes de la interfaz (que no deben depender unas de otras) abstraídas en clases.

Saludos
Responder
#7
MUCHAS GRACIAS.

Con las listas es suficiente. La verdad es que las clases están siendo un quebradero de cabeza. Con funciones y demás todo me funciona correctamente en la aplicación pero claro se repite código y luego vienen los puristas y empiezan las críticas que si te estás repitiendo, que si la filosofía de python es "DONT YOU REPEAT", que si eso es un mal código..... etc ect.

Lo triste es que todo funciona perfectamente cuando lo hago a mí manera aunque sea repitiendo código. (Gracias a Geany es sencillisimo "duplicar" un código cambiando simplemente el nombre de la variable con el comando replace).

Pero bueno, quizá me concentré en hacer las cosas a mí manera y cuando domine esto a la perfección me pueda enzarzar con el tema de las clases, herencia, etc y pueda simplificar el código de la app.

Gracias de nuevo.
Responder
#8
Exactamente... ese tipo de conceptos van llegando solos a medida que uno se adentra con mayor profundidad en la programación.

Saludos
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)