E
Effectively eti_cuadrado is a defined variable within the function and therefore is local by default, as the return function ceases to exist and therefore is inaccessible from outside the same.You have many options:Make it globaldef modificar_ancho(valor):
texte = str(valor) + "X" + str(al.get())
presenta.set(texte)
eti_cuadrado.config(width=2*an.get())
def modificar_alto(valor):
texte = str(an.get()) + "X" + str(valor)
presenta.set(texte)
eti_cuadrado.config(height=al.get())
def abrir_ventana2():
global eti_cuadrado
ventana2 = tk.Toplevel(ventana) # crea una segunda ventana
ventana2.title("Cuadrado a escala")
ventana2.geometry("400x320")
al.set(1) # Inicializa el Scale vertical.
an.set(1) # Inicializa el Scale horizontal.
presenta.set("")
alto = tk.Scale(ventana2, from_=1, to=10, length=200,
label="Altura", variable=al, tickinterval="1",
command=modificar_alto)
alto.place(x=0, y=10)
ancho = tk.Scale(ventana2, from_=1, to=15, length=300,
label="Anchura", variable=an, tickinterval="1",
orient="horizontal",
command=modificar_ancho)
ancho.place(x=40, y=230)
eti_cuadrado = tk.Label(ventana2, bg="lightgreen", textvar=presenta, bd=10,
relief="raised")
eti_cuadrado.place(x=90, y=50)
Global variables should be avoided as much as possible, it is best to use them only for constants. It's more will not work if you want to create multiple secondary windows simultaneously as you overwrite the variable eti_cuadrado in every call to the function.Passing the label as an argumentThis can be achieved with lambda functions or a normal one that acts as wrapper:def modificar_ancho(valor, label):
texte = str(valor) + "X" + str(al.get())
presenta.set(texte)
label.config(width=2*an.get())
def modificar_alto(valor, label):
texte = str(an.get()) + "X" + str(valor)
presenta.set(texte)
label.config(height=al.get())
def abrir_ventana2():
ventana2 = tk.Toplevel(ventana) # crea una segunda ventana
ventana2.title("Cuadrado a escala")
ventana2.geometry("400x320")
al.set(1) # Inicializa el Scale vertical.
an.set(1) # Inicializa el Scale horizontal.
presenta.set("")
eti_cuadrado = tk.Label(ventana2, bg="lightgreen", textvar=presenta, bd=10,
relief="raised")
eti_cuadrado.place(x=90, y=50)
alto = tk.Scale(
ventana2, from_=1, to=10, length=200, label="Altura",
variable=al, tickinterval="1",
command=lambda val, label=eti_cuadrado: (modificar_alto(val, label))
)
alto.place(x=0, y=10)
ancho = tk.Scale(
ventana2, from_=1, to=15, length=300, label="Anchura", variable=an,
tickinterval="1", orient="horizontal",
command=lambda val, label=eti_cuadrado: (modificar_ancho(val, label))
)
ancho.place(x=40, y=230)
For a more detailed explanation you can look at the following question: https://es.stackoverflow.com/q/346778/15089 Declaring functions within abrir_ventana2def abrir_ventana2():
def modificar_ancho(valor):
texte = str(valor) + "X" + str(al.get())
presenta.set(texte)
eti_cuadrado.config(width=2*an.get())
def modificar_alto(valor):
texte = str(an.get()) + "X" + str(valor)
presenta.set(texte)
eti_cuadrado.config(height=al.get())
ventana2 = tk.Toplevel(ventana) # crea una segunda ventana
ventana2.title("Cuadrado a escala")
ventana2.geometry("400x320")
al.set(1) # Inicializa el Scale vertical.
an.set(1) # Inicializa el Scale horizontal.
presenta.set("")
alto = tk.Scale(ventana2, from_=1, to=10, length=200,
label="Altura", variable=al, tickinterval="1",
command=modificar_alto)
alto.place(x=0, y=10)
ancho = tk.Scale(ventana2, from_=1, to=15, length=300,
label="Anchura", variable=an, tickinterval="1",
orient="horizontal",
command=modificar_ancho)
ancho.place(x=40, y=230)
eti_cuadrado = tk.Label(ventana2, bg="lightgreen", textvar=presenta, bd=10,
relief="raised")
eti_cuadrado.place(x=90, y=50)
Use POO and represent each window with a classI think it's the most elegant and most scalable option without a doubt:import tkinter as tk
class MainWindow(tk.Frame):
def init(self, parent=None):
super().init(parent)
tk.Button(
self, text="Abir ventana", command=self.abrir_ventana_secundaria
).pack()
def abrir_ventana_secundaria(self):
VentanaSecundaria(self)
class VentanaSecundaria(tk.Toplevel):
def init(self, parent=None):
super().init(parent)
self.title("Cuadrado a escala")
self.geometry("400x320")
self.al = tk.IntVar(self, 1)
self.an = tk.IntVar(self, 1)
self.presenta = tk.StringVar(self, "")
tk.Scale(self, from_=1, to=10, length=200,
label="Altura", variable=self.al, tickinterval="1",
command=self.modificar_alto).place(x=0, y=10)
tk.Scale(self, from_=1, to=15, length=300,
label="Anchura", variable=self.an, tickinterval="1",
orient="horizontal",
command=self.modificar_ancho).place(x=40, y=230)
self.eti_cuadrado = tk.Label(
self, bg="lightgreen", textvar=self.presenta,
bd=10, relief="raised"
)
self.eti_cuadrado.place(x=90, y=50)
def modificar_ancho(self, valor):
texte = f"{valor}X{self.al.get()}"
self.presenta.set(texte)
self.eti_cuadrado.config(width=2 * self.an.get())
def modificar_alto(self, valor):
texte = f"{self.an.get()}X{valor}"
self.presenta.set(texte)
self.eti_cuadrado.config(height=self.al.get())
if name == "main":
ventana = tk.Tk()
ventana.title("Cuadrado")
ventana.geometry("380x320")
ventana.resizable(False, False)
MainWindow(ventana).pack(side="top", fill="both", expand=True)
ventana.mainloop()
Now I'm going to try to explain why every one of your attempts doesn't work:Declaring the function by setting the name of the windows with a
point:If you do this:ventana.ventana2.eti_cuadrado.config(height=al.get())
height is static, when called config is obtained at that time the value of the variable and is assigned to heigh. If it changes anything then it changes.Put the height and width in the "Label" declaration by assigning the
VariScale values:eti_cuadrado = tk.Label(ventana2, bg="lightgreen", textvar=presenta, bd=10,
width=2*an.get(), height=al.get(), relief="raised")
the problem is the same as before, when widget is used, the value of the variables (which will be 0) is obtained and assigned to width and height. When the variables are modified, nothing will change.Send as parameter the "eti_box" tag to the functions modify_alto and modify_ancho:command=modificar_alto(eti_cuadrado)
in this case your solution would be similar to my second solution. It doesn't work because what You're passin' command is the return of the function (None In this case) when you must pass the reference to it so that it can be called cuanod the event takes place.