paint-brush
Construyendo su primera GUI de Python con Tkinterpor@pictureinthenoise
1,803 lecturas
1,803 lecturas

Construyendo su primera GUI de Python con Tkinter

por Picture in the Noise13m2022/11/14
Read on Terminal Reader
Read this story w/o Javascript

Demasiado Largo; Para Leer

Tkinter es el estándar de Python para crear GUI y se incluye con la biblioteca estándar de Python. Esta guía recorre el diseño de una aplicación GUI simple para explicar los conceptos básicos de Tkinter, incluido el diseño de los elementos de la GUI, la captura de la entrada del usuario y la vinculación de los elementos de la GUI a los métodos de devolución de llamada.

People Mentioned

Mention Thumbnail
featured image - Construyendo su primera GUI de Python con Tkinter
Picture in the Noise HackerNoon profile picture

Introducción

Quizás acaba de empezar a aprender Python y ha creado una o dos aplicaciones sencillas. ¡Felicidades! Pero, ¿ahora qué? Bueno, ¿qué tal construir una interfaz gráfica de usuario ("GUI") para interactuar con su nueva y brillante aplicación de Python?


Hay varias opciones para crear aplicaciones GUI con Python, incluidas PyQt y wxPython . Esta guía, sin embargo, le presentará Tkinter .


Tkinter , que significa "interfaz Tk", es el estándar de Python para crear GUI y se incluye con la biblioteca estándar de Python . Es un enlace al kit de herramientas Tk GUI , una biblioteca gratuita de código abierto de widgets GUI que se puede usar para construir interfaces gráficas en una variedad de lenguajes de programación.


Este tutorial recorre el diseño de una aplicación GUI básica que muestra la hora local en una zona horaria seleccionada por el usuario. Los pasos crean la aplicación progresivamente y describen algunos de los conceptos clave cuando se trabaja con Tkinter , incluido el diseño de los elementos de la GUI, la captura de la entrada del usuario y la vinculación de los elementos de la GUI a los métodos de devolución de llamada.


requisitos previos

Para completar esta guía, necesitará tener:


  • Pitón instalado .
  • pip instalada.
  • Se instaló la biblioteca de zona horaria pytz . La biblioteca se puede instalar usando pip .


 pip install pytz


Esta guía utilizará la terminología ventana raíz y ventana principal indistintamente.


Paso 1: cree una nueva aplicación de Python y configure las importaciones requeridas

Cree una nueva aplicación de Python llamada timezone.py y agregue las siguientes declaraciones de import para importar los módulos Tkinter , datetime y pytz .


 import tkinter as tk import datetime import pytz


Paso 2: agregar zonas horarias

Esta guía incorpora el conjunto de zonas horarias de Estados Unidos que son una pequeña fracción de las zonas horarias admitidas por pytz . La funcionalidad de la aplicación se puede ampliar agregando nombres de zona horaria pytz adicionales. Se puede generar una lista completa de zonas horarias disponibles con pytz ejecutando el siguiente comando:


 print(pytz.all_timezones)


El conjunto de zonas horarias de Estados Unidos disponibles a través pytz se especifica como una lista.


 import tkinter as tk import datetime import pytz timezones = ["US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", "US/Pacific", "US/Samoa"]


Paso 3: crea una instancia de la clase Tk

La instanciación de la clase Tk crea una ventana raíz que servirá como la ventana principal de la GUI de la aplicación de zona horaria.


 import tkinter as tk import datetime import pytz timezones = ["US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", "US/Pacific", "US/Samoa"] root = tk.Tk()


Paso 4: configure la ventana principal

Este paso configura la ventana raíz, particularmente su título, geometría y capacidad de cambio de tamaño.

Paso 4a: configuración del título de la ventana principal

El título de la ventana se establece mediante el método del title .


 import tkinter as tk import datetime import pytz timezones = ["US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", "US/Pacific", "US/Samoa"] root = tk.Tk() root.title("Simple Timezone Application")

Paso 4b: configuración del ancho y la altura de la ventana principal

Los valores de ancho y alto de la ventana, expresados en píxeles, se pueden asignar a variables para facilitar el seguimiento del código.


 import tkinter as tk import datetime import pytz timezones = ["US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", "US/Pacific", "US/Samoa"] root = tk.Tk() root.title("Simple Timezone Application") window_width = 450 window_height = 175

Paso 4c: Cálculo de la posición central de la ventana principal

La ventana principal se puede colocar en cualquier parte de la pantalla, por ejemplo, en el centro, en la esquina superior izquierda, etc. Una ventana centrada proporciona un "aspecto" agradable y la posición central de la ventana principal se puede determinar utilizando el ancho de pantalla de la ventana winfo_screenwidth() y métodos winfo_screenheight() junto con algunas matemáticas simples. Estos dos métodos devuelven el ancho y la altura de la pantalla que se utilizan para calcular las coordenadas (x,y) apropiadas para centrar la ventana principal. Al igual que con el ancho y el alto de la ventana, los valores de la posición central también se pueden asignar a las variables para que el código sea más legible.


 import tkinter as tk import datetime import pytz timezones = ["US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", "US/Pacific", "US/Samoa"] root = tk.Tk() root.title("Simple Timezone Application") window_width = 450 window_height = 175 screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() center_x = int((screen_width - window_width)/2) center_y = int((screen_height - window_height)/2)


Tenga en cuenta que los valores center_x y center_y también se expresan en píxeles y se usa int para garantizar que ambos valores calculados sean números enteros.

Paso 4d - Configuración de la geometría de la ventana principal

La geometría de la ventana root , que especifica el tamaño y la posición de la ventana principal, se establece mediante el método de geometry de la ventana raíz. Para simplificar las cosas, puede usar un literal de cadena con formato, o f-string , que interpolará las expresiones de la variable de geometría en tiempo de ejecución. Según el siguiente bloque de código, el literal f-string se pasa al método de geometry como parámetro.


 import tkinter as tk import datetime import pytz timezones = ["US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", "US/Pacific", "US/Samoa"] root = tk.Tk() root.title("Simple Timezone Application") window_width = 450 window_height = 175 screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() center_x = int((screen_width - window_width)/2) center_y = int((screen_height - window_height)/2) root.geometry(f"{window_width}x{window_height}+{center_x}+{center_y}")


Paso 4e: configuración del cambio de tamaño de la ventana principal


La capacidad de cambio de tamaño de la ventana raíz a lo largo de sus ejes x e y se puede configurar a través del método de cambio de resizable de la ventana raíz. El método resizable acepta parámetros de height y width , en ese orden. Un valor True o distinto de cero para cualquiera de los parámetros especifica que la ventana principal se puede cambiar de tamaño a lo largo del eje asociado. Un valor False o 0 para cualquiera de los parámetros especifica que la ventana principal no se puede cambiar de tamaño a lo largo del eje dado. La aplicación del temporizador utilizará un valor de False tanto para el alto como para el ancho para evitar que se cambie el tamaño de la ventana principal.


 import tkinter as tk import datetime import pytz timezones = ["US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", "US/Pacific", "US/Samoa"] root = tk.Tk() root.title("Simple Timezone Application") window_width = 450 window_height = 175 screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() center_x = int((screen_width - window_width)/2) center_y = int((screen_height - window_height)/2) root.geometry(f"{window_width}x{window_height}+{center_x}+{center_y}") root.resizable(False, False)


Paso 5: especifique una cuadrícula para el diseño del widget

Los widgets se pueden organizar en la parte superior de la ventana principal de diferentes maneras mediante los administradores de geometría . En general, los widgets se pueden organizar de 3 maneras:


  1. Empaquetado usando el método pack() . El administrador de geometría pack() organiza los widgets en bloques antes de agregarlos a una ventana raíz o widget principal. Una forma imperfecta pero quizás útil de pensar en empacar es pensar en agregar artículos comestibles a una bolsa de compras. Los elementos no se agregan necesariamente a ubicaciones predefinidas en la bolsa. Más bien, se empaquetan uno tras otro, utilizando el espacio disponible hasta que todos los artículos se han colocado en la bolsa. El administrador de geometría pack() funciona de manera similar.

  2. Colocado usando el método place() . El administrador de geometría place() coloca los widgets en posiciones específicas predefinidas en la ventana raíz o el widget principal. Este administrador de geometría es obviamente útil cuando se crean diseños de GUI precisos.

  3. Organizado como una cuadrícula usando el método grid() . Las cuadrículas son tablas bidimensionales de filas y columnas. Los widgets se agregan a una cuadrícula especificando la fila y la columna en particular donde se debe colocar el widget. Las cuadrículas se configuran utilizando los métodos columnconfigure y rowconfigure de la ventana raíz. Cada uno de estos métodos tiene un index y un atributo de weight . El atributo index especifica la posición de la columna o fila utilizando una base inicial de 0 . El atributo de weight especifica el tamaño de una columna o fila en particular en relación con otras columnas. Por ejemplo, si la columna 0 tiene peso 1 y la columna 1 tiene peso 3 , entonces la columna 1 será 3 veces más grande que la columna 0 .


Las cuadrículas son útiles cuando se colocan elementos uno al lado del otro y son relativamente simples de implementar. La aplicación de zona horaria utilizará una cuadrícula de ventana principal dividida en 4 columnas iguales.


 import tkinter as tk import datetime import pytz timezones = ["US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", "US/Pacific", "US/Samoa"] root = tk.Tk() root.title("Simple Timezone Application") window_width = 450 window_height = 175 screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() center_x = int((screen_width - window_width)/2) center_y = int((screen_height - window_height)/2) root.geometry(f"{window_width}x{window_height}+{center_x}+{center_y}") root.resizable(False, False) root.columnconfigure(0, weight=1) root.columnconfigure(1, weight=1) root.columnconfigure(2, weight=1) root.columnconfigure(3, weight=1)


Paso 6 - Agregar widgets

En este paso, los widgets se agregan a la cuadrícula de la ventana principal definida en el Paso 4. La aplicación de zona horaria utilizará 3 widgets de TKinter :


  • Label
  • Listbox
  • Button


Los widgets de Label y Button de Tkinter son exactamente como se nombran. El widget de Label permite al programador mostrar texto (es decir, una etiqueta), y el widget de Button se usa para mostrar botones. El widget Listbox se utiliza para seleccionar un valor (o valores) de una lista de opciones.

Por supuesto, hay otros widgets además de los 3 que se enumeran arriba, como los SpinBox , Entry y Message . La documentación formal de los comandos de Tk es un recurso útil para obtener más información sobre los widgets disponibles a través del kit de herramientas de Tk.

Paso 6a - Crear widgets

Se crea una instancia de cada clase de widget para un widget determinado utilizado con el diseño de GUI. La aplicación de zona horaria utiliza 4 instancias de widgets: 2 widgets de Label , 1 widget de Listbox de lista y 1 widget de Button .


 import tkinter as tk import datetime import pytz timezones = ["US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", "US/Pacific", "US/Samoa"] root = tk.Tk() root.title("Simple Timezone Application") window_width = 450 window_height = 175 screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() center_x = int((screen_width - window_width)/2) center_y = int((screen_height - window_height)/2) root.geometry(f"{window_width}x{window_height}+{center_x}+{center_y}") root.resizable(False, False) root.columnconfigure(0, weight=1) root.columnconfigure(1, weight=1) root.columnconfigure(2, weight=1) root.columnconfigure(3, weight=1) # Instance of Label widget class for selection prompt. select_timezone_label = tk.Label(root, text="Please select a timezone.") # Instance of Listbox class for selection of timezone from list. list_var = tk.Variable(value=timezones) select_timezone_listbox = tk.Listbox(root, listvariable=list_var, height=1) # Instance of Button class to get the local time in the selected timezone. select_timezone_button = tk.Button(root, text="Get Time") # Second instance of the Label class to display the local time in the selected timezone. time_label = tk.Label(root, text="")


Como se ve en el bloque de código anterior, cada instancia de widget está "adjunta" a la ventana root . El widget Listbox también requiere la instanciación de una clase especial Tkinter Variable() que se utiliza para proporcionar al widget la lista de opciones de zona horaria que el usuario puede seleccionar a través del atributo Listbox listvariable . El texto que muestra cada widget de Label se puede configurar mediante el atributo de text . El valor de texto para time_label se deja en blanco, ya que se establecerá dinámicamente cada vez que el usuario "obtenga" la hora de una zona horaria seleccionada.

Paso 6b - Coloque los widgets en la cuadrícula

Las instancias del widget creadas en el Paso 5a se pueden colocar en la cuadrícula definida en el Paso 4 usando el método grid() . La aplicación de zona horaria utilizará los siguientes atributos del método grid() para definir el diseño:


  • column : especifica la columna particular donde se colocará el widget utilizando una base 0 .

  • row : especifica la fila particular donde se colocará el widget utilizando una base 0 .

  • columnspan : especifica que el widget debe abarcar el número especificado de columnas. Por ejemplo, un widget con un valor columnspan=3 abarcará 3 columnas incluso si el widget en sí es más pequeño que 3 columnas.

  • sticky : el comportamiento predeterminado de Tkinter es colocar un widget en el centro horizontal y vertical de la celda (es decir, en una posición particular de fila/columna) donde se coloca. Este comportamiento predeterminado se puede anular utilizando el atributo sticky que utiliza valores similares a los de una brújula, incluidos NW , N , NE , W , E , SW , S y SE , para alinear el widget en una ubicación particular dentro de la celda del widget. Por ejemplo, sticky=tK.W especifica que el widget debe alinearse con la esquina oeste de su celda de cuadrícula. De manera análoga, sticky=tK.E especifica que el widget debe alinearse con la esquina este de su celda de cuadrícula.

  • padx , pady : los atributos padx y pady se usan para agregar relleno en el eje x y el eje y respectivamente con valores especificados en píxeles. Naturalmente, el relleno puede proporcionar una GUI de aspecto más profesional, lo que garantiza que los widgets no "golpeen" directamente contra los bordes de la ventana raíz u otros widgets.


 import tkinter as tk import datetime import pytz timezones = ["US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", "US/Pacific", "US/Samoa"] root = tk.Tk() root.title("Simple Timezone Application") window_width = 450 window_height = 175 screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() center_x = int((screen_width - window_width)/2) center_y = int((screen_height - window_height)/2) root.geometry(f"{window_width}x{window_height}+{center_x}+{center_y}") root.resizable(False, False) root.columnconfigure(0, weight=1) root.columnconfigure(1, weight=1) root.columnconfigure(2, weight=1) root.columnconfigure(3, weight=1) # Instance of Label widget class for selection prompt. select_timezone_label = tk.Label(root, text="Please select a timezone.") # Instance of Listbox class for selection of timezone from list. list_var = tk.Variable(value=timezones) select_timezone_listbox = tk.Listbox(root, listvariable=list_var, height=1) # Instance of Button class to get the local time in the selected timezone. select_timezone_button = tk.Button(root, text="Get Time") # Second instance of the Label class to display the local time in the selected timezone. time_label = tk.Label(root, text="") # Place widgets on grid. select_timezone_label.grid(column=0, row=0, columnspan=4, sticky=tk.W, padx=10, pady=10) select_timezone_listbox.grid(column=0, row=1, columnspan=3, sticky=tk.EW, padx=10, pady=10) select_timezone_button.grid(column=4, row=1, sticky=tk.E, padx=10, pady=10) time_label.grid(column=0, row=4, columnspan=4, sticky=tk.W, padx=10, pady=10)


Paso 7: cree el método de devolución de llamada del botón Obtener tiempo

Se debe definir un método de devolución de llamada para manejar eventos cuando el usuario hace clic en el botón select_timezone_button creado en el Paso 5.

Paso 7a: enlace del botón Obtener tiempo

Antes de definir la lógica de devolución de llamada, es útil enlazar primero el botón con el nombre del método que eventualmente abarcará el código de devolución de llamada. El método bind() se puede usar junto con una función lambda para vincular select_timezone_button al método de devolución de llamada especificado. Además, tenga en cuenta que la función lambda se usa para pasar referencias a los widgets select_timezone_listbox y time_label como parámetros de devolución de llamada. Estos parámetros de devolución de llamada en realidad no son necesarios ya que select_timezone_listbox y time_label están dentro del alcance global. Sin embargo, podría decirse que es útil demostrar cómo se pueden pasar argumentos a la función de devolución de llamada.


 import tkinter as tk import datetime import pytz timezones = ["US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", "US/Pacific", "US/Samoa"] root = tk.Tk() root.title("Simple Timezone Application") window_width = 450 window_height = 175 screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() center_x = int((screen_width - window_width)/2) center_y = int((screen_height - window_height)/2) root.geometry(f"{window_width}x{window_height}+{center_x}+{center_y}") root.resizable(False, False) root.columnconfigure(0, weight=1) root.columnconfigure(1, weight=1) root.columnconfigure(2, weight=1) root.columnconfigure(3, weight=1) # Instance of Label widget class for selection prompt. select_timezone_label = tk.Label(root, text="Please select a timezone.") # Instance of Listbox class for selection of timezone from list. list_var = tk.Variable(value=timezones) select_timezone_listbox = tk.Listbox(root, listvariable=list_var, height=1) # Instance of Button class to get the local time in the selected timezone. select_timezone_button = tk.Button(root, text="Get Time") # Second instance of the Label class to display the local time in the selected timezone. time_label = tk.Label(root, text="") # Place widgets on grid. select_timezone_label.grid(column=0, row=0, columnspan=4, sticky=tk.W, padx=10, pady=10) select_timezone_listbox.grid(column=0, row=1, columnspan=3, sticky=tk.EW, padx=10, pady=10) select_timezone_button.grid(column=4, row=1, sticky=tk.E, padx=10, pady=10) time_label.grid(column=0, row=4, columnspan=4, sticky=tk.W, padx=10, pady=10) select_timezone_button.bind("<Button>", lambda e, args=[select_timezone_listbox, time_label]: get_timezone_time(e, args))

Paso 7b: definición de la lógica de devolución de llamada

La lógica de devolución de llamada para manejar eventos de clic de botón se define a continuación.


 def get_timezone_time(e, args): select_timezone_listbox = args[0] time_label = args[1] selection_index = select_timezone_listbox.curselection() selected_timezone = select_timezone_listbox.get(selection_index) now_time = datetime.datetime.now() tz_time = now_time.astimezone(pytz.timezone(selected_timezone)) tz_formatted = tz_time.strftime("%H:%M:%S") time_label.configure({"text": f"The time in {selected_timezone} is {tz_formatted}."}) time_label.update()


Los curselection() y get() se utilizan para recuperar la zona horaria seleccionada por el usuario desde la referencia al widget select_timezone_listbox . La hora actual del usuario se convierte luego en la hora de la zona horaria seleccionada. Finalmente, el método configure se usa para cambiar el atributo de text de la referencia a time_label con la hora local en la zona horaria seleccionada. Tenga en cuenta que el método update() se usa para "forzar" al widget time_label a actualizarse con el nuevo valor de texto.

Paso 8: complete y ejecute la aplicación

El método mainloop() de la ventana raíz se aplica como la última línea de código. El método mainloop() ejecutará la GUI en un bucle infinito hasta que el usuario salga.


El código completo es el siguiente:


 import tkinter as tk import datetime import pytz timezones = ["US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", "US/Pacific", "US/Samoa"] def get_timezone_time(e, args): select_timezone_listbox = args[0] time_label = args[1] selection_index = select_timezone_listbox.curselection() selected_timezone = select_timezone_listbox.get(selection_index) now_time = datetime.datetime.now() tz_time = now_time.astimezone(pytz.timezone(selected_timezone)) tz_formatted = tz_time.strftime("%H:%M:%S") time_label.configure({"text": f"The time in {selected_timezone} is {tz_formatted}."}) time_label.update() root = tk.Tk() root.title("Simple Timezone Application") window_width = 450 window_height = 175 screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() center_x = int((screen_width - window_width)/2) center_y = int((screen_height - window_height)/2) root.geometry(f"{window_width}x{window_height}+{center_x}+{center_y}") root.resizable(False, False) root.columnconfigure(0, weight=1) root.columnconfigure(1, weight=1) root.columnconfigure(2, weight=1) root.columnconfigure(3, weight=1) # Instance of Label widget class for selection prompt. select_timezone_label = tk.Label(root, text="Please select a timezone.") # Instance of Listbox class for selection of timezone from list. list_var = tk.Variable(value=timezones) select_timezone_listbox = tk.Listbox(root, listvariable=list_var, height=1) # Instance of Button class to get the local time in the selected timezone. select_timezone_button = tk.Button(root, text="Get Time") # Second instance of the Label class to display the local time in the selected timezone. time_label = tk.Label(root, text="") # Place widgets on grid. select_timezone_label.grid(column=0, row=0, columnspan=4, sticky=tk.W, padx=10, pady=10) select_timezone_listbox.grid(column=0, row=1, columnspan=3, sticky=tk.EW, padx=10, pady=10) select_timezone_button.grid(column=4, row=1, sticky=tk.E, padx=10, pady=10) time_label.grid(column=0, row=4, columnspan=4, sticky=tk.W, padx=10, pady=10) # Bind button to callback. select_timezone_button.bind("<Button>", lambda e, args=[select_timezone_listbox, time_label]: get_timezone_time(e, args)) root.mainloop()


Cuando se inicia la aplicación, la GUI debería verse así:




Para usar la aplicación, haga clic en el cuadro de lista y use las teclas de cursor arriba/abajo de su teclado para desplazarse por las opciones de zona horaria. Haga clic en el botón Obtener hora para mostrar la hora actual en su zona horaria seleccionada.




Próximos pasos

¡Felicitaciones por crear su primera aplicación GUI de Python con Tkinter ! Como se mencionó en la Introducción, esta guía fue diseñada para presentarle algunos conceptos básicos. La documentación de la biblioteca estándar de Python y las referencias de la documentación de los comandos Tk mencionadas anteriormente son dos recursos fantásticos para ayudarlo a conocer las funciones y funciones más avanzadas de Tkinter.


Las aplicaciones GUI de Tkinter a veces son criticadas por tener una apariencia no nativa. Eso puede ser cierto. Pero los widgets del kit de herramientas son altamente configurables y las aplicaciones GUI de Tkinter se pueden construir con relativa rapidez sin necesidad de instalar ningún paquete externo de Python.


Más allá de la documentación formal, existen innumerables tutoriales disponibles a través de Internet para aprender a crear aplicaciones GUI más sofisticadas con Tkinter.