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).

Código:
import tkinter as tk
from tkinter import ttk
from datetime import *
from tkinter import messagebox
import time
import calendar
import psycopg2
import threading
from threading import Timer
import os
import sys



class Prueba:

def __init__(self):

self.principal = tk.Tk()
self.principal.title("Prueba NOTEBOOK")
self.principal.geometry('600x600')

# FUNTIONS

def addcliente():

self.pest2 = ttk.Frame(self.note)
self.note.add(self.pest2, text='CLIENTE')

# LABELS PESTAÑAS

self.lab = ttk.Label(self.pest2, text='NOMBRE')
self.lab.grid(row=0, column=0)

self.lab1 = ttk.Label(self.pest2, text='APELLIDOS')
self.lab1.grid(row=0, column=1)

self.lab2 = ttk.Label(self.pest2, text='EDAD')
self.lab2.grid(row=0, column=2)

# ENTRYS PESTAÑAS

self.ent = ttk.Entry(self.pest2)
self.ent.grid(row=1, column=0, padx=10)

self.ent1 = ttk.Entry(self.pest2)
self.ent1.grid(row=1, column=1, padx=10)

# COMBOBOS PESTAÑAS

self.com = ttk.Combobox(self.pest2, width=3)
self.com.grid(row=1, column=2, padx=10)

def valcliente():

self.ent.configure(state='disabled')
self.ent1.configure(state='disabled')

def modcliente():

self.ent.configure(state='!disabled')
self.ent1.configure(state='!disabled')




# FRAMES

self.frame1 = ttk.Frame(self.principal)
self.frame1.grid(row=0, column=0)

self.frame2 = ttk.Frame(self.principal)
self.frame2.grid(row=1, column=0)

# NOTEBOOKS

self.note = ttk.Notebook(self.frame1, height=200)
self.note.grid()

self.pest1 = ttk.Frame(self.note)
self.note.add(self.pest1, text='CLIENTE')

# LABELS

self.lab = ttk.Label(self.pest1, text='NOMBRE')
self.lab.grid(row=0, column=0)

self.lab1 = ttk.Label(self.pest1, text='APELLIDOS')
self.lab1.grid(row=0, column=1)

self.lab2 = ttk.Label(self.pest1, text='EDAD')
self.lab2.grid(row=0, column=2)

# ENTRYS

self.ent = ttk.Entry(self.pest1)
self.ent.grid(row=1, column=0, padx=10)

self.ent1 = ttk.Entry(self.pest1)
self.ent1.grid(row=1, column=1, padx=10)

# COMBOBOX

self.com = ttk.Combobox(self.pest1, width=3)
self.com.grid(row=1, column=2, padx=10)

# BUTTONS

self.but = ttk.Button(self.frame2, text='Añadir', command=addcliente)
self.but.grid(row=1, column=0, padx=5)

self.but1 = ttk.Button(self.frame2, text='Validar', command=valcliente)
self.but1.grid(row=1, column=1, padx=5)

self.but2 = ttk.Button(self.frame2, text='Modificar', command= modcliente)
self.but2.grid(row=1, column=2, padx=5)



self.principal.mainloop()




def main():
my_app = Prueba()

if __name__ == '__main__':
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
¡No te pierdas nuestro curso oficial en Udemy para aprender Python, bases de datos SQL, orientación a objetos, tkinter y mucho más!

También ofrecemos consultoría profesional de desarrollo en Python para personas y empresas.
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!
¡No te pierdas nuestro curso oficial en Udemy para aprender Python, bases de datos SQL, orientación a objetos, tkinter y mucho más!

También ofrecemos consultoría profesional de desarrollo en Python para personas y empresas.
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.

Código:
class Addpest():



def __init__(self):


def addcliente():



self.pest2 = ttk.Frame(self.note)

self.note.add(self.pest2, text='CLIENTE')



# LABELS PESTAÑAS



self.lab = ttk.Label(self.pest2, text='NOMBRE')
self.lab.grid(row=0, column=0)

self.lab1 = ttk.Label(self.pest2, text='APELLIDOS')
self.lab1.grid(row=0, column=1)



self.lab2 = ttk.Label(self.pest2, text='EDAD')

self.lab2.grid(row=0, column=2)



# ENTRYS PESTAÑAS



self.ent = ttk.Entry(self.pest2)

self.ent.grid(row=1, column=0, padx=10)



self.ent1 = ttk.Entry(self.pest2)

self.ent1.grid(row=1, column=1, padx=10)



# COMBOBOS PESTAÑAS



self.com = ttk.Combobox(self.pest2, width=3)

self.com.grid(row=1, column=2, padx=10)





class Prueba():



def __init__(self):



self.principal = tk.Tk()

self.principal.title("Prueba NOTEBOOK")

self.principal.geometry('600x600')



def valcliente():



self.ent.configure(state='disabled')

self.ent1.configure(state='disabled')



def modcliente():



self.ent.configure(state='!disabled')

self.ent1.configure(state='!disabled')



# FRAMES



self.frame1 = ttk.Frame(self.principal)

self.frame1.grid(row=0, column=0)



self.frame2 = ttk.Frame(self.principal)

self.frame2.grid(row=1, column=0)



# NOTEBOOKS



self.note = ttk.Notebook(self.frame1, height=200)

self.note.grid()



self.pest1 = ttk.Frame(self.note)

self.note.add(self.pest1, text='CLIENTE')



# LABELS



self.lab = ttk.Label(self.pest1, text='NOMBRE')

self.lab.grid(row=0, column=0)



self.lab1 = ttk.Label(self.pest1, text='APELLIDOS')

self.lab1.grid(row=0, column=1)



self.lab2 = ttk.Label(self.pest1, text='EDAD')

self.lab2.grid(row=0, column=2)



# ENTRYS



self.ent = ttk.Entry(self.pest1)

self.ent.grid(row=1, column=0, padx=10)



self.ent1 = ttk.Entry(self.pest1)

self.ent1.grid(row=1, column=1, padx=10)



# COMBOBOX



self.com = ttk.Combobox(self.pest1, width=3)

self.com.grid(row=1, column=2, padx=10)



# BUTTONS



self.but = ttk.Button(self.frame2, text='Añadir', command=Addpest.addcliente)

self.but.grid(row=1, column=0, padx=5)



self.but1 = ttk.Button(self.frame2, text='Validar', command=valcliente)

self.but1.grid(row=1, column=1, padx=5)



self.but2 = ttk.Button(self.frame2, text='Modificar', command= modcliente)

self.but2.grid(row=1, column=2, padx=5)







self.principal.mainloop()









def main():

my_app = Prueba()



if __name__ == '__main__':

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
¡No te pierdas nuestro curso oficial en Udemy para aprender Python, bases de datos SQL, orientación a objetos, tkinter y mucho más!

También ofrecemos consultoría profesional de desarrollo en Python para personas y empresas.
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
¡No te pierdas nuestro curso oficial en Udemy para aprender Python, bases de datos SQL, orientación a objetos, tkinter y mucho más!

También ofrecemos consultoría profesional de desarrollo en Python para personas y empresas.
Responder


Salto de foro:


Usuarios navegando en este tema: 2 invitado(s)