R
The error is due to the when it is evaluated the line:datos=pro.get(), pre.get(), can.get(), var.get()
this line is evaluated when running the function agregarbefore even the composition of the app is complete and displayed on screen (before the mainloop). At that time all entries are logically empty so to crear He's always sent a tupla with four empty chains..You must. get the four values at the time the button is pressedNot when the function is called. There are many ways to do this, but without modifying your original idea it can simply be worthwhile that the lambda expressions are evaluated in deferred, that is, when they are called and not being defined:import sqlite3
import tkinter as tk
def crear(datos1):
con = sqlite3.connect("Inventario")
cur = con.cursor()
try:
cur.execute("INSERT INTO INVENTARIO VALUES(NULL,?,?,?,?)", datos1)
con.commit()
tk.messagebox.showinfo("Agregar","Registro Agregado")
except:
tk.messagebox.showwarning("Error","Ha ocurrido un error")
finally:
cur.close()
con.close()
def agregar():
root = tk.Tk()
pro = tk.StringVar(root)
pre = tk.StringVar(root)
can = tk.StringVar(root)
var = tk.StringVar(root)
frame1 = tk.Frame(root)
frame1.pack()
entry1 = tk.Entry(frame1, textvariable=pro)
entry1.grid(row=1, column=1, padx=10, pady=10)
entry2 = tk.Entry(frame1, textvariable=pre)
entry2.grid(row=2, column=1, padx=10, pady=10)
entry3 = tk.Entry(frame1, textvariable=can)
entry3.grid(row=3, column=1, padx=10, pady=10)
rb1 = tk.Radiobutton(frame1, text="Producto", variable=var, value="Producto")
rb1.grid(row=4, column=1, sticky="w")
rb2 = tk.Radiobutton(frame1, text="Servicio", variable=var, value="Servicio")
rb2.grid(row=5, column=1, sticky="w")
label1 = tk.Label(frame1, text="Producto:")
label1.grid(row=1, column=0, padx=10, pady=10, sticky="w")
label2 = tk.Label(frame1, text="Precio:")
label2.grid(row=2, column=0, padx=10, pady=10, sticky="w")
label3 = tk.Label(frame1, text="Cantidad:")
label3.grid(row=3, column=0, padx=10, pady=10, sticky="w")
label4 = tk.Label(frame1, text="Tipo:")
label4.grid(row=4, column=0, padx=10, pady=10, sticky="w")
frame2 = tk.Frame(root)
frame2.pack()
crear_wrapper = lambda: crear((pro.get(), pre.get(), can.get(), var.get()))
boton1 = tk.Button(frame2, text="Agregar", command=crear_wrapper)
boton1.grid(row=1, column=0, padx=5)
boton2 = tk.Button(frame2, text="Cancelar", command=root.destroy)
boton2.grid(row=1, column=1, padx=5)
root.mainloop()
if name == "main":
agregar()
Note that you do not need to use lambda if the function does not receive arguments, it is enough to pass a reference to the function in this case (command=root.destroy instead of command=lambda:root.destroy()(c): https://es.stackoverflow.com/questions/270617/c%c3%b3mo-actuan-las-funciones-lambda-en-este-c%c3%b3digo EditionSince the added function is launched by pressing a button in another window, you should consider some more things:Always pass the father to the widgetsincluding variables (StringVar, IntVaretc.). You must not use more than one instance in principle. tkinter.Tk implementation. If you need more windows use TopLevelLook at this related question: https://es.stackoverflow.com/q/283262/15089 Your function should remain:def agregar(root=None):
window = Toplevel(root)
pro = StringVar(window)
pre = StringVar(window)
can = StringVar(window)
var = StringVar(window)
frame1 = Frame(window)
frame1.pack()
entry1 = Entry(frame1, textvariable=pro)
entry1.grid(row=1, column=1, padx=10, pady=10)
entry2 = Entry(frame1, textvariable=pre)
entry2.grid(row=2, column=1, padx=10, pady=10)
entry3 = Entry(frame1, textvariable=can)
entry3.grid(row=3, column=1, padx=10, pady=10)
rb1 = Radiobutton(frame1, text="Producto", variable=var, value="Producto")
rb1.grid(row=4, column=1, sticky="w")
rb2 = Radiobutton(frame1, text="Servicio", variable=var, value="Servicio")
rb2.grid(row=5, column=1, sticky="w")
label1 = Label(frame1, text="Producto:")
label1.grid(row=1, column=0, padx=10, pady=10, sticky="w")
label1 = Label(frame1, text="Precio:")
label1.grid(row=2, column=0, padx=10, pady=10, sticky="w")
label1 = Label(frame1, text="Cantidad:")
label1.grid(row=3, column=0, padx=10, pady=10, sticky="w")
label1 = Label(frame1, text="Tipo:")
label1.grid(row=4, column=0, padx=10, pady=10, sticky="w")
frame2 = Frame(window)
frame2.pack()
boton1 = Button(frame2, text="Agregar", command=lambda: crear((pro.get(), pre.get(), can.get(), var.get())))
boton1.grid(row=1, column=0, padx=5)
boton2=Button(frame2, text="Cancelar", command=window.destroy)
boton2.grid(row=1, column=1, padx=5)
window.mainloop()
and you must call it by:invMenu.add_command(label="Agregar Item", command=lambda: F.agregar(root))