Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
[tkinter] Importar al programa principal las funciones de otro modulo
#1
Hola otra vez!  Big Grin

Pues cuando creia que era sencillo, no logro resolver esta situacion...

A medida que creamos una GUI con tkinter, es normal que usemos funciones propias que son llamadas por los propios command de los widgets creados.
Pero claro, el programa principal se empieza a llenar de esas funciones y widgets. Creia que era tan sencillo como crear esas funciones en otro modulo y que fueran importada por el programa principal. Pero me da errores. He intentado, incluso, la importacion de tkinter y algunas de sus clases en los modulos que se importan. Pero no logro solucionarlo. Pongo un ejemplo muy simple para ver si asi se entiende mejor:

Modulo principal:

Código:
from tkinter import Tk, Button, Label
from funciones import saludo


# PROGRAMA PRINCIPAL
ventana = Tk()
ventana.geometry('300x300')

btn_saludo = Button(ventana, text = 'Saluda', command = saludo)
btn_saludo.place(x = 10, y = 50)



ventana.mainloop()

Modulo que se importa con la funcion:

Código:
from tkinter import Label


# MODULO FUNCIONES
def saludo():
   lbl_saludo = Label(ventana, text = 'Hola')
   lbl_saludo.place(x = 10, y = 10)

Y claro, me da el tipico error:

Exception in Tkinter callback
Traceback (most recent call last): 
    lbl_saludo = Label(ventana, text = 'Hola')
NameError: name 'ventana' is not defined


Puedo entender por donde va la cosa. Pero no se como configurar los modulos para no sobrecargar de codigo el programa principal. Entiendo que 'ventana' no esta en el modulo que importamos. Pero si se encuentra creada en el modulo principal. Al hacer la importacion del modulo funciones es cuando se da cuenta que no existe ventana en dicho modulo.

Muchas gracias por adelantado!
Responder
#2
Hola, puedes resolverlo pasando como argumento la ventana a las funciones de tu módulo, a través de functools.partial():

  1. from functools import partial
  2.  
  3. btn_saludo = Button(ventana, text='Saluda', command=partial(saludo, ventana))


Luego tu función debe aceptar ese argumento:

  1. def saludo(ventana):
  2. lbl_saludo = Label(ventana, text = 'Hola')
  3. lbl_saludo.place(x = 10, y = 10)


Saludos!
Responder
#3
Lo primero de todo ¡Feliz año nuevo!  Smile

Pues una vez mas, gracias! 

Funciona a la perfeccion. Lo que me extraña que esto no este mas detallado o explicado en los manuales o guias de tkinter. Y mas cuando suelen recomendar modular en varios scripts los codigos mas extensos. Creo que nunca hubiera dado con la solucion. Incluso en tu blog hay una entrada que explica este modulo a la perfeccion. Pero creo, yo no hubiera imaginado su uso para la duda que tenia.

Esta es la entrada de tu blog:

https://recursospython.com/guias-y-manuales/functools/

Ahora me tocara investigar cuando la funcion que importamos al modulo principal admite argumentos. Supongo que habra que recurrir a lambda para ese fin. 

¡Un saludo y feliz 2019!
Responder
#4
Me alegro que te haya servido! Un muy feliz año para vos también Wink

Saludos
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)