Función en Python

(1/2) > >>

Sk9ITk5Z:
Buenos días como están? espero me puedan ayudar con una duda que tengo.
Estoy haciendo un sistema de recepción de equipos en python, lo voy a crear por partes, soy principiante apenas estoy aprendiendo el lenguaje. Tengo una función donde creo cuadros de texto para meter datos(de clientes), y otra función donde debo tomar el dato que metí en el cuadro de texto para poder guardar esa información en una tabla(clientes) de una base de datos pero me da error en la función del botón de alta ya que dice que no esta definida una variable en este caso son las variables de ID, Nombre, etc.... les pego el código a ver si me pueden ayudar...



Código
# Crear la función para el boton Cliente
def clientes():
   ventana2 = tkinter.Toplevel(ventana)
   ventana2.title("Alta de Clientes")
   ventana2.geometry("500x250")
 
   # Crear etiquetas
   etiquetaID = Label(ventana2, text="ID:")
   etiquetaID.grid(row=0, column=0)
 
   etiquetaNombre = Label(ventana2, text="Nombre:")
   etiquetaNombre.grid(row=1, column=0)
 
   etiquetaDireccion = Label(ventana2, text="Dirección:")
   etiquetaDireccion.grid(row=2, column=0)
 
   etiquetaTelefono = Label(ventana2, text="Teléfono:")
   etiquetaTelefono.grid(row=3, column=0)
 
   # Crear cuadros de texto
   cuadroID = Entry(ventana2)
   cuadroID.grid(row=0, column=1)
 
   cuadroNombre = Entry(ventana2)
   cuadroNombre.grid(row=1, column=1)
 
   cuadroDireccion = Entry(ventana2)
   cuadroDireccion.grid(row=2, column=1)
 
   cuadroTelefono = Entry(ventana2)
   cuadroTelefono.grid(row=3, column=1)
 
   # Crear botones
   botonAlta = Button(ventana2, text="Dar de Alta", command=alta)
   botonAlta.grid(row=4, column=0)
 
   botonBorrar = Button(ventana2, text="Dar de Baja", command=baja)
   botonBorrar.grid(row=4, column=1)
 

aca   debo tomar esos datos:

Código
# Crear la función para el boton Alta
def alta():
   id_cliente = cuadroID.get() #-------------------aqui me da el error, en obtener esa informacion
   nombre_cliente = cuadroNombre.get()
   direccion_cliente = cuadroDireccion.get()
   telefono_cliente = cuadroTelefono.get()
 
   # Agregar los datos a la tabla de la base de datos
   datos = [id_cliente, nombre_cliente, direccion_cliente, telefono_cliente]
   cursor.execute("INSERT INTO tabla_clientes VALUES (?, ?, ?, ?)", datos)
   conexion.commit()
 
 

Locura_23:
Hola, tu problema es que las variables no son accesibles desde el metodo alta(), además no veo que utilices StringVar(), por lo que sé, el componente Entry tiene que asociarse a una variable tipo StringVar() para que puedas guardar el contenido del entry.
Entonces lo que tenes que hacer es guardar el contenido que el usuario introduce en el componente Entry con una variable StringVar() y luego en el evento del botón de 'dar alta' le tienes que pasar la referencia a la función que procesa el evento y además el CONTENIDO de Entry.
Fijate este ejemplo muy simple:

Código
import tkinter
 
def evento_enviar(entradaNombre):
   print(f'Usuario ingresó: {entradaNombre.get()}')
 
def main():
   ventana = tkinter.Tk()
   ventana.geometry('600x400')
 
   tkinter.Label(ventana, text='Ingrese su nombre --> ').grid(row=0, column=0)
 
   entradaNombre = tkinter.StringVar()
 
   tkinter.Entry(ventana, width=30, textvariable=entradaNombre).grid(row=0, column=1)
 
   tkinter.Button(ventana, text='Enviar',
       command=lambda: evento_enviar(entradaNombre)).grid(row=0, column=2)
 
   ventana.mainloop()
 
if __name__ == '__main__':
   main()
 

Por ultimo nota que esto tambien se podria solucionar si utilizas POO, donde podrias hacer que los datos sean atributos de la clase y por lo tanto compartidos a lo largo del codigo de la clase.

Sk9ITk5Z:
Cita de: Locura_23 en 24 Marzo 2023, 21:55 pm

Hola, tu problema es que las variables no son accesibles desde el metodo alta(), además no veo que utilices StringVar(), por lo que sé, el componente Entry tiene que asociarse a una variable tipo StringVar() para que puedas guardar el contenido del entry.
Entonces lo que tenes que hacer es guardar el contenido que el usuario introduce en el componente Entry con una variable StringVar() y luego en el evento del botón de 'dar alta' le tienes que pasar la referencia a la función que procesa el evento y además el CONTENIDO de Entry.
Fijate este ejemplo muy simple:

Código
import tkinter
 
def evento_enviar(entradaNombre):
   print(f'Usuario ingresó: {entradaNombre.get()}')
 
def main():
   ventana = tkinter.Tk()
   ventana.geometry('600x400')
 
   tkinter.Label(ventana, text='Ingrese su nombre --> ').grid(row=0, column=0)
 
   entradaNombre = tkinter.StringVar()
 
   tkinter.Entry(ventana, width=30, textvariable=entradaNombre).grid(row=0, column=1)
 
   tkinter.Button(ventana, text='Enviar',
       command=lambda: evento_enviar(entradaNombre)).grid(row=0, column=2)
 
   ventana.mainloop()
 
if __name__ == '__main__':
   main()
 

Por ultimo nota que esto tambien se podria solucionar si utilizas POO, donde podrias hacer que los datos sean atributos de la clase y por lo tanto compartidos a lo largo del codigo de la clase.


Gracias por responder a lo que veo solo es una manera diferente de hacerlo, ya hice las modificaciones que me diste pero el problema es el mismo en la linea 42 dice variable no definida, te pego el código completo:

Código
import tkinter
from tkinter import *
import sqlite3
 
# Crear una ventana principal
ventana = tkinter.Tk()
ventana.title("Entorno Gráfico")
ventana.geometry("500x250")
 
# Crear la función para el boton Cliente
def clientes():
   ventana2 = tkinter.Toplevel(ventana)
   ventana2.title("Alta de Clientes")
   ventana2.geometry("500x250")
 
   # Crear etiquetas
   tkinter.Label(ventana2, text='ID:').grid(row=0, column=0)
   tkinter.Label(ventana2, text='Nombre:').grid(row=1, column=0)
   tkinter.Label(ventana2, text='Direccion:').grid(row=2, column=0)
   tkinter.Label(ventana2, text='Telefono').grid(row=3, column=0)
 
   # Crear cuadros de texto
   cuadroID = tkinter.StringVar()
   tkinter.Entry(ventana2, width=30, textvariable=cuadroID).grid(row=0, column=1)
 
   cuadroNombre = tkinter.StringVar()
   tkinter.Entry(ventana2, width=30, textvariable=cuadroNombre).grid(row=1, column=1)
 
   cuadroDireccion = tkinter.StringVar()
   tkinter.Entry(ventana2, width=30, textvariable=cuadroDireccion).grid(row=2, column=1)
 
   cuadroTelefono = tkinter.StringVar()
   tkinter.Entry(ventana2, width=30, textvariable=cuadroTelefono).grid(row=3, column=1)
 
   # Crear botones
   tkinter.Button(ventana2, text='Dar de Alta',command=alta).grid(row=4, column=2)
   tkinter.Button(ventana2, text='Dar de Baja',command=baja).grid(row=4, column=1)
 
 
# Crear la función para el boton Alta
def alta():
   id_cliente = cuadroID.get()
   nombre_cliente = cuadroNombre.get()
   direccion_cliente = cuadroDireccion.get()
   telefono_cliente = cuadroTelefono.get()
 
   # Agregar los datos a la tabla de la base de datos
   datos = [id_cliente, nombre_cliente, direccion_cliente, telefono_cliente]
   cursor.execute("INSERT INTO tabla_clientes VALUES (?, ?, ?, ?)", datos)
   conexion.commit()
 
# Crear la función para el boton Baja
def baja():
   id_cliente = cuadroID.get()
   cursor.execute("DELETE FROM tabla_clientes WHERE id = ?", [id_cliente])
   conexion.commit()
 
# Crear el boton Clientes
botonClientes = Button(ventana, text="Clientes", command=clientes)
botonClientes.grid(row=0, column=0)
 
# Crear la conexión con la base de datos
conexion = sqlite3.connect("base_datos.db")
cursor = conexion.cursor()
 
# Iniciar el programa
ventana.mainloop()
 

Locura_23:
mm ya veo, pues en realidad el problema sigue siendo este: el alcance de tus variables o donde las variables pueden utilizarse, tenes que organizar tu codigo en bloques para que te guies qué datos le estas enviando a las funciones.

Python no te impone ninguna forma de codear pero en general siempre es mejor utilizar una estructura en tus programas. Es decir, tendrias que organizar tu codigo en funciones o clases.

considera este refactor, le agregue las explicaciones en forma de comentarios, la funcion main() es la principal y llama agregar_cliente, en agregar_cliente se ingresan los datos pero a diferencia de antes, una mejor opcion es encapsularlos en una unidad tipo cliente, por ejemplo un diccionario. Este cliente (encapsulado) se manda a la funcion alta o baja, de manera que estas funciones pueden procesar al cliente.

pruebalo y me comentas si tienes dudas:

Código
import tkinter
import sqlite3
'''from tkinter import * esto puede traer problemas, te conviene importar solo
lo que necesitas usar'''
 
# Crear la función para el boton Cliente
def agregar_cliente(ventana):
   # Crear etiquetas
   tkinter.Label(ventana, text='ID:').grid(row=1, column=0)
   tkinter.Label(ventana, text='Nombre:').grid(row=2, column=0)
   tkinter.Label(ventana, text='Direccion:').grid(row=3, column=0)
   tkinter.Label(ventana, text='Telefono').grid(row=4, column=0)
 
   # Crear cuadros de texto
   cuadroID = tkinter.StringVar()
   tkinter.Entry(ventana, width=30, textvariable=cuadroID).grid(row=1, column=1)
 
   cuadroNombre = tkinter.StringVar()
   tkinter.Entry(ventana, width=30, textvariable=cuadroNombre).grid(row=2, column=1)
 
   cuadroDireccion = tkinter.StringVar()
   tkinter.Entry(ventana, width=30, textvariable=cuadroDireccion).grid(row=3, column=1)
 
   cuadroTelefono = tkinter.StringVar()
   tkinter.Entry(ventana, width=30, textvariable=cuadroTelefono).grid(row=4, column=1)
 
   '''cuando llamas al boton dar de alta, creas un diccionario o estructura de datos
   del cliente, de manera que esta todo encapsulado en una unidad'''
 
   # Crear botones
   tkinter.Button(ventana, text='Dar de Alta',
           command=lambda: alta(
               {
               'id': cuadroID.get(),
               'nombre': cuadroNombre.get(),
               'direccion': cuadroDireccion.get(),
               'telefono': cuadroTelefono.get()
               }
           )).grid(row=5, column=0)
 
   '''lo mismo en baja'''
 
   tkinter.Button(ventana, text='Dar de Baja',
           command=lambda: baja(
               {
               'id': cuadroID.get(),
               'nombre': cuadroNombre.get(),
               'direccion': cuadroDireccion.get(),
               'telefono': cuadroTelefono.get()
               }
           )).grid(row=5, column=1)
 
 
# Crear la función para el boton Alta
def alta(cliente):
 
   '''
   id_cliente = cuadroID.get()
   nombre_cliente = cuadroNombre.get()
   direccion_cliente = cuadroDireccion.get()
   telefono_cliente = cuadroTelefono.get()
 
   # Agregar los datos a la tabla de la base de datos
   datos = [id_cliente, nombre_cliente, direccion_cliente, telefono_cliente]
   cursor.execute("INSERT INTO tabla_clientes VALUES (?, ?, ?, ?)", datos)
   conexion.commit()
   '''
 
   '''la funcion alta recibe ya un cliente en forma de estructura de datos'''
 
   print(f'Se dara de alta: {cliente}')
   print(f"Tiene ID:' {cliente['id']}")
   print(f"Tiene nombre: {cliente['nombre']}")
 
# Crear la función para el boton Baja
def baja(cliente):
 
   '''
   id_cliente = cuadroID.get()
   cursor.execute("DELETE FROM tabla_clientes WHERE id = ?", [id_cliente])
   conexion.commit()
   '''
 
   '''lo mismo la funcion baja'''
   print(f'Se dara de baja: {cliente}')
 
def main():
   # Crear una ventana principal
   ventana = tkinter.Tk()
   ventana.title("Entorno Gráfico")
   ventana.geometry("500x250")
 
   # Crear la conexión con la base de datos
   conexion = sqlite3.connect("base_datos.db")
   cursor = conexion.cursor()
 
   '''aca llamas a la funcion agregar_cliente y le pasas la referencia
   de la ventana padre'''
   # Crear el boton Clientes
   botonClientes = tkinter.Button(ventana, text="Clientes",
           command=lambda:agregar_cliente(ventana) )
 
   botonClientes.grid(row=0, column=0)
 
   # Iniciar el programa
   ventana.mainloop()
 
if __name__ == '__main__':
   main()

Sk9ITk5Z:
Cita de: Locura_23 en 25 Marzo 2023, 01:29 am

mm ya veo, pues en realidad el problema sigue siendo este: el alcance de tus variables o donde las variables pueden utilizarse, tenes que organizar tu codigo en bloques para que te guies qué datos le estas enviando a las funciones.

Python no te impone ninguna forma de codear pero en general siempre es mejor utilizar una estructura en tus programas. Es decir, tendrias que organizar tu codigo en funciones o clases.

considera este refactor, le agregue las explicaciones en forma de comentarios, la funcion main() es la principal y llama agregar_cliente, en agregar_cliente se ingresan los datos pero a diferencia de antes, una mejor opcion es encapsularlos en una unidad tipo cliente, por ejemplo un diccionario. Este cliente (encapsulado) se manda a la funcion alta o baja, de manera que estas funciones pueden procesar al cliente.

pruebalo y me comentas si tienes dudas:

Código
import tkinter
import sqlite3
'''from tkinter import * esto puede traer problemas, te conviene importar solo
lo que necesitas usar'''
 
# Crear la función para el boton Cliente
def agregar_cliente(ventana):
   # Crear etiquetas
   tkinter.Label(ventana, text='ID:').grid(row=1, column=0)
   tkinter.Label(ventana, text='Nombre:').grid(row=2, column=0)
   tkinter.Label(ventana, text='Direccion:').grid(row=3, column=0)
   tkinter.Label(ventana, text='Telefono').grid(row=4, column=0)
 
   # Crear cuadros de texto
   cuadroID = tkinter.StringVar()
   tkinter.Entry(ventana, width=30, textvariable=cuadroID).grid(row=1, column=1)
 
   cuadroNombre = tkinter.StringVar()
   tkinter.Entry(ventana, width=30, textvariable=cuadroNombre).grid(row=2, column=1)
 
   cuadroDireccion = tkinter.StringVar()
   tkinter.Entry(ventana, width=30, textvariable=cuadroDireccion).grid(row=3, column=1)
 
   cuadroTelefono = tkinter.StringVar()
   tkinter.Entry(ventana, width=30, textvariable=cuadroTelefono).grid(row=4, column=1)
 
   '''cuando llamas al boton dar de alta, creas un diccionario o estructura de datos
   del cliente, de manera que esta todo encapsulado en una unidad'''
 
   # Crear botones
   tkinter.Button(ventana, text='Dar de Alta',
           command=lambda: alta(
               {
               'id': cuadroID.get(),
               'nombre': cuadroNombre.get(),
               'direccion': cuadroDireccion.get(),
               'telefono': cuadroTelefono.get()
               }
           )).grid(row=5, column=0)
 
   '''lo mismo en baja'''
 
   tkinter.Button(ventana, text='Dar de Baja',
           command=lambda: baja(
               {
               'id': cuadroID.get(),
               'nombre': cuadroNombre.get(),
               'direccion': cuadroDireccion.get(),
               'telefono': cuadroTelefono.get()
               }
           )).grid(row=5, column=1)
 
 
# Crear la función para el boton Alta
def alta(cliente):
 
   '''
   id_cliente = cuadroID.get()
   nombre_cliente = cuadroNombre.get()
   direccion_cliente = cuadroDireccion.get()
   telefono_cliente = cuadroTelefono.get()
 
   # Agregar los datos a la tabla de la base de datos
   datos = [id_cliente, nombre_cliente, direccion_cliente, telefono_cliente]
   cursor.execute("INSERT INTO tabla_clientes VALUES (?, ?, ?, ?)", datos)
   conexion.commit()
   '''
 
   '''la funcion alta recibe ya un cliente en forma de estructura de datos'''
 
   print(f'Se dara de alta: {cliente}')
   print(f"Tiene ID:' {cliente['id']}")
   print(f"Tiene nombre: {cliente['nombre']}")
 
# Crear la función para el boton Baja
def baja(cliente):
 
   '''
   id_cliente = cuadroID.get()
   cursor.execute("DELETE FROM tabla_clientes WHERE id = ?", [id_cliente])
   conexion.commit()
   '''
 
   '''lo mismo la funcion baja'''
   print(f'Se dara de baja: {cliente}')
 
def main():
   # Crear una ventana principal
   ventana = tkinter.Tk()
   ventana.title("Entorno Gráfico")
   ventana.geometry("500x250")
 
   # Crear la conexión con la base de datos
   conexion = sqlite3.connect("base_datos.db")
   cursor = conexion.cursor()
 
   '''aca llamas a la funcion agregar_cliente y le pasas la referencia
   de la ventana padre'''
   # Crear el boton Clientes
   botonClientes = tkinter.Button(ventana, text="Clientes",
           command=lambda:agregar_cliente(ventana) )
 
   botonClientes.grid(row=0, column=0)
 
   # Iniciar el programa
   ventana.mainloop()
 
if __name__ == '__main__':
   main()



Gracias lo pruebo y te aviso...

Navegación

[0] Índice de Mensajes

[#] Página Siguiente