I am designing a project that is based on saving information on domestic gas cylinders for a community, first a window is opened where the number of cylinders to be registered is entered, then a combobox with the data already assigned is shown in another window, only select them, when I give the save button the empty values appear help
this is the code
from tkinter import *
from tkinter import Toplevel, getint, ttk
ventana = Tk()
class cilin:
def __init__(self, empresa, tamano, pico):
self.empresa = empresa.pack(), empresa.bind("<<ComboboxSelected>>", lambda _: empresa.get())
self.tamano = tamano.pack(), tamano.get()
self.pico = pico.pack(), pico.get()
def __str__(self):
return f"Empresa: {self.empresa} , Tamano: {self.tamano} , Pico: {self.pico} "
def ejecucion():
can = cantidad.get() 1
ventana2 = Toplevel()
for cilindros in range(1, can ,1):
titulo = LabelFrame(ventana2, text= f"Cilindro {cilindros}")
titulo.pack()
objeto = cilin(
empresa = ttk.Combobox(titulo, values=["Radelco", "PacoGas", "Comunal"]),
tamano = ttk.Combobox(titulo, values=["Pequena", "Mediana", "Regular", "Grande"]),
pico = ttk.Combobox(titulo, values=["Pequeno", "Mediano", "Grande"]))
def guardar():
print(*lista)
lista.append(objeto)
Button(ventana2, text="Guardar", command=guardar).pack()
lista = []
cantidad = IntVar()
Label(ventana, text="cantidad cilindros").pack()
Entry(ventana, textvariable=cantidad).pack()
Button(ventana, text="listo", command=ejecucion).pack()
ventana.mainloop()
And this is what he throws at the end
Empresa: (None, '18560064<lambda>') , Tamano: (None, '') , Pico: (None, '')
CodePudding user response:
The main problem is that after for example:
self.tamano = tamano.pack(), tamano.get() # Returns: ( None, '' )
# tamano.pack() returns None
# tamano.get() gets the contents of tamano a few millisecnds after creation.
I've amended your code to save each successive lista
into a total_list
which prints after the GUI is closed.
from tkinter import *
from tkinter import Toplevel, getint, ttk
ventana = Tk()
class cilin:
def __init__(self, empresa, tamano, pico):
# Keep references to the objects
self.empresa = empresa
self.tamano = tamano
self.pico = pico
# Pack the objects
empresa.pack()
tamano.pack()
pico.pack()
def get( self ):
return self.empresa.get(), self.tamano.get(), self.pico.get()
def __str__(self):
# Call get on the Comboboxes to show results.
e, t, p = self.get()
return f"Empresa: { e } , Tamano: { t } , Pico: { p } "
def ejecucion():
can = cantidad.get() 1
ventana2 = Toplevel()
lista = [] # Make lista local. It lists the objects in the current ventana2
for cilindros in range(1, can ,1):
titulo = LabelFrame(ventana2, text= f"Cilindro {cilindros}")
titulo.pack()
objeto = cilin(
empresa = ttk.Combobox(titulo, values=["Radelco", "PacoGas", "Comunal"]),
tamano = ttk.Combobox(titulo, values=["Pequena", "Mediana", "Regular", "Grande"]),
pico = ttk.Combobox(titulo, values=["Pequeno", "Mediano", "Grande"]))
lista.append( objeto )
def guardar():
for obj in lista:
print( obj )
total_list.append( obj.get() ) # Store the results
ventana2.destroy()
# If not destroyed each call to ejecucion will add more and
# more frames and comboboxes which are no longer used.
Button(ventana2, text="Guardar", command=guardar).pack()
total_list = [] # A new list to accumulate the data collected.
cantidad = IntVar()
Label(ventana, text="cantidad cilindros").pack()
Entry(ventana, textvariable=cantidad).pack()
Button(ventana, text="listo", command=ejecucion).pack()
ventana.mainloop()
print( total_list )
CodePudding user response:
I rewrote your code in a OO way.
To do what you want, if I understand correctly, you have to keep a reference to all the combo widgets you create when the window opens.
Here I use a dictionary and then I loop on it to retrieve the right values, if I understand well what you want to do.
I also set a maximum quantity available, 6, and a check on the text box to see if maybe someone think of ordering 0 ;)
#!/usr/bin/python3
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
class UI(tk.Toplevel):
def __init__(self, parent, items=None):
super().__init__(name="details")
self.parent = parent
self.items = items
self.empresa = ("Radelco", "PacoGas", "Comunal")
self.tamano = ("Pequena", "Mediana", "Regular", "Grande")
self.pico = ("Pequeno", "Mediano", "Grande")
self.dict_cilindros = {}
self.init_ui()
def init_ui(self):
f0 = ttk.Frame(self)
for item in range(self.items):
msg = "Cilindro {0}".format(item 1)
f1 = ttk.LabelFrame(f0,text= msg)
ttk.Label(f1, text = "Empresa").pack()
empresa= ttk.Combobox(f1,state='readonly',values=self.empresa)
empresa.pack()
ttk.Label(f1, text = "Tamano").pack()
tamano = ttk.Combobox(f1,state='readonly',values=self.tamano)
tamano.pack()
ttk.Label(f1, text = "Pico").pack()
pico = ttk.Combobox(f1,state='readonly',values=self.pico)
pico.pack()
self.dict_cilindros[item]=(empresa, tamano, pico)
f1.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
f2 = ttk.Frame(f0,)
bts = [("Listo", 0, self.on_listo, "<Alt-l>"),
("Cerrar", 0, self.on_cancel, "<Alt-c>")]
for btn in bts:
ttk.Button(f2,
text=btn[0],
underline=btn[1],
command = btn[2]).pack(fill=tk.X, padx=5, pady=5)
self.parent.bind(btn[3], btn[2])
f2.pack(side=tk.RIGHT, fill=tk.Y, expand=0)
f0.pack(fill=tk.BOTH, expand=1)
def on_open(self):
msg = "Ha solicitado {0} cilindros".format(self.items)
self.title(msg)
def on_listo(self, evt=None):
for k,v in self.dict_cilindros.items():
print("Detalle Cilindro {0}".format(k 1))
for i in v:
print(i.get())
def on_cancel(self, evt=None):
self.destroy()
class Main(ttk.Frame):
def __init__(self, parent, ):
super().__init__(name="main")
self.parent = parent
self.obj = None
self.cantidad = tk.IntVar()
self.cantidad.set(1)
self.maximo = 6
self.init_ui()
def init_ui(self):
f0 = ttk.Frame(self)
f1 = ttk.Frame(f0,)
ttk.Label(f1, text = "Qantidad Cilindros", ).pack()
self.txTest = ttk.Entry(f1, textvariable=self.cantidad).pack()
f2 = ttk.Frame(f0,)
bts = [("Guardar", 0, self.on_guardar, "<Alt-g>"),
("Cerrar", 0, self.on_close, "<Alt-c>")]
for btn in bts:
ttk.Button(f2,
text=btn[0],
underline=btn[1],
command = btn[2]).pack(fill=tk.X, padx=5, pady=5)
self.parent.bind(btn[3], btn[2])
f1.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
f2.pack(side=tk.RIGHT, fill=tk.Y, expand=0)
f0.pack(fill=tk.BOTH, expand=1)
def on_guardar(self, evt=None):
if self.cantidad.get() !=0:
if self.cantidad.get() <= self.maximo:
self.obj = UI(self, self.cantidad.get())
self.obj.on_open()
else:
msg = "Puede solicitar al máximo {0} cilindros.".format(self.maximo)
messagebox.showinfo(self.master.title(), msg, parent=self)
else:
msg = "No puedes preguntar cero!"
messagebox.showinfo(self.master.title(), msg, parent=self)
def on_close(self, evt=None):
if self.obj:
self.obj.destroy()
self.parent.on_exit()
class App(tk.Tk):
def __init__(self):
super().__init__()
self.protocol("WM_DELETE_WINDOW", self.on_exit)
self.title("Hello World")
Main(self).pack(fill=tk.BOTH, expand=1)
def on_exit(self):
"""Close all"""
msg = "Cerrar?"
if messagebox.askokcancel(self.title(), msg, parent=self):
self.destroy()
def main():
app = App()
app.mainloop()
if __name__ == '__main__':
main()