Python - ¿Cómo guardo un valor en una variable externa?

CorePress2024-01-25  10

La duda era la siguiente, quiero seleccionar una fecha usando la librería tkcalendar, está seleccionada correctamente, pero no puedo usar la variable fuera de la función.

def dateentry_view():
    def print_sel():
        date = cal.get_date()
        print(date)
    top = tk.Toplevel(root)

    ttk.Label(top, text='Elige el día').pack()
    cal = DateEntry(top)
    cal.pack(padx=10, pady=10)
    ttk.Button(top, text="Aceptar", command=print_sel).pack()

¿Cómo puedo pasar la variable de fecha para mostrarla en una Etiqueta de la siguiente manera?

labelDate = Label(root,textvariable=date)

He intentado poner la etiqueta dentro de la función, pero todavía no muestra la variable de fecha.

def dateentry_view():
    
    top = tk.Toplevel(root)

    ttk.Label(top, text='Elige el día').pack()
    cal = DateEntry(top)
    cal.pack(padx=10, pady=10)
    ttk.Button(top, text="Aceptar", command=print_sel).pack() 

    def print_sel():
         date = cal.get_date()
         print(date)
         labelFecha = Label(root,textvariable=date)

Cuando imprimo fecha me muestra la fecha que he seleccionado correctamente.

Lea sobre las palabras clave globales y no locales de Python.

– Michael Butscher

27/03/2021 a las 19:38

¡Aquí no se necesita global/no local! Cada vez que utilices esas palabras clave, probablemente te estés preparando para sufrir dolores de cabeza.

- Samsagaz

27/03/2021 a las 19:47

@MichaelButscher Nunca supe que existía una palabra clave no local. Me importaría dar un poco de explicación.?

- TheLizzard

27/03/2021 a las 20:09

@TheLizzard: Puedes leer sobre esto en la documentación.

- martineau

27/03/2021 a las 21:12



------------------------------------

Al buscar en Google tk.Label, parece que la idea de textvariable es que se refiere a un tk.StringVar mutable, no a un str normal de Python (que es inmutable). De ahí todolo que debes hacer es declarar StringVar en el alcance externo y luego actualizarlo dentro de la devolución de llamada:

    date = tk.StringVar()
    def set_date():
         date.set(cal.get_date())

    ttk.Button(top, text="Aceptar", command=set_date).pack() 
    labelFecha = Label(root, textvariable=date)



------------------------------------

No estás usando la opción textvariable- correctamente. Debe establecerle una referencia a una instancia de una clase variable tk.StringVar. Luego, cualquier cambio en el valor de la variable actualizará automáticamente lo que muestra el widget.

Tenga en cuenta también que el método tkcalendar.DateEntry.get_date() devuelve un datetime.date, no una cadena, por lo que necesitará un manual para convertirlo usted mismo en uno antes de establecerle el valor de StringVar.

Aquí hay un ejemplo ejecutable.calificando lo que estoy diciendo:

import tkinter as tk
import tkinter.ttk as ttk
from tkcalendar import DateEntry


def dateentry_view():
    def print_sel():
        date = cal.get_date()  # Get datetime.date.
        fechaStr = date.strftime('%Y-%m-%d')  # Convert datetime.date to string.
        fechaVar.set(fechaStr)  # Update StringVar with formatted date.
        top.destroy()  # Done.

    top = tk.Toplevel(root)

    ttk.Label(top, text='Elige el día').pack()
    cal = DateEntry(top)
    cal.pack(padx=10, pady=10)
    ttk.Button(top, text="Aceptar", command=print_sel).pack()


root = tk.Tk()

ttk.Button(root, text="Ejecutar prueba", command=dateentry_view).pack()
fechaVar = tk.StringVar(value='<no date>')  # Create and initialize control variable.
labelFecha = tk.Label(root, textvariable=fechaVar)  # Use it.
labelFecha.pack()

root.mainloop()

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare