Interfícies Gràfiques amb Tkinter¶
Introducció¶
Tkinter és la biblioteca estàndard de Python per crear interfícies gràfiques d'usuari (GUI). Forma part de la instal·lació de Python i no requereix cap dependència externa. Internament fa servir la biblioteca Tk, disponible a Windows, macOS i Linux.
Els exemples d'aquest mòdul provenen de la sèrie de vídeos "Tkinter Basics" d'Alan D Moore i del repositori Tkinter-By-Example. Al llarg dels vídeos es construeix progressivament una aplicació de diari personal (My Diary) que va incorporant nous conceptes en cada lliurament.
Pots ampliar els teus coneixements amb el llibre d'Alan: Python GUI Programming with Tkinter.
Estructura dels exemples¶
Tots els exemples es troben a pys/ organitzats per vídeo:
| Carpeta | Conceptes principals |
|---|---|
pys/Video1/ |
Finestra, widgets bàsics, layout grid |
pys/Video2/ |
Funcions, callbacks, barra d'estat, guardar fitxer |
pys/Video3/ |
Variables de control (StringVar, BooleanVar), trace |
pys/Video4/ |
Frame, LabelFrame, Scrollbar |
pys/Video5/ |
Diàlegs (messagebox, simpledialog, filedialog) |
pys/Video6/ |
Menú (Menu), mida de lletra dinàmica |
pys/Video7/ |
Radiobutton, color de fons, marca de data |
pys/Video8/ |
ttk: widgets amb tema, Notebook, Combobox, Treeview |
pys/Video9/ |
ttk.Style: personalització visual i temes |
Conceptes per vídeo¶
Video 1 — Finestra i widgets bàsics¶
- Crear la finestra principal amb
tk.Tk() - Configurar títol, mida i pes de files/columnes amb
columnconfigure/rowconfigure - Widgets:
Label,Entry,Listbox,Text,Button - Sistema de layout
gridamb opcionssticky,padx,pady,columnspan
import tkinter as tk
root = tk.Tk()
root.title('My Diary')
root.geometry('800x600')
root.columnconfigure(1, weight=1)
root.rowconfigure(2, weight=1)
tk.Label(root, text='Subject: ').grid(sticky='we', padx=5, pady=5)
tk.Entry(root).grid(row=0, column=1, sticky=tk.E + tk.W)
root.mainloop()
Video 2 — Funcions i desar fitxers¶
- Associar una funció a un botó amb
configure(command=...) - Llegir el contingut dels widgets amb
.get()i.get('1.0', tk.END) - Barra d'estat dinàmica amb
Label - Desar dades en un fitxer de text
def save():
subject = subject_inp.get()
message = message_inp.get('1.0', tk.END)
with open(f'{subject}.txt', 'w') as fh:
fh.write(message)
status_bar.configure(text='Fitxer desat')
save_btn.configure(command=save)
Video 3 — Variables de control i trace¶
StringVar,BooleanVar,IntVar: variables observables vinculades a widgetsOptionMenuper a llistes desplegablesCheckbuttonper a opcions booleanestrace_add('write', callback)per reaccionar a canvis de valor en temps real
subject_var = tk.StringVar()
cat_var = tk.StringVar()
def check_filename(*args):
filename = f'{cat_var.get()} - {subject_var.get()}.txt'
if Path(filename).exists():
status_var.set(f'AVÍS: {filename} ja existeix!')
subject_var.trace_add('write', check_filename)
cat_var.trace_add('write', check_filename)
Video 4 — Frame, LabelFrame i Scrollbar¶
Frameper agrupar widgets i simplificar el layoutLabelFrameper a grups amb títol visibleScrollbarvinculada a un widgetTextambyscrollcommandiyview
message_frame = tk.LabelFrame(root, text='Missatge')
message_frame.columnconfigure(0, weight=1)
message_inp = tk.Text(message_frame)
message_inp.grid(sticky='nesw')
scrollbar = tk.Scrollbar(message_frame)
scrollbar.grid(row=0, column=1, sticky='nse')
scrollbar.configure(command=message_inp.yview)
message_inp.configure(yscrollcommand=scrollbar.set)
Video 5 — Diàlegs estàndard¶
tkinter.messagebox:showinfo,askokcanceltkinter.simpledialog:askstringper demanar text a l'usuaritkinter.filedialog:askopenfilenameper seleccionar un fitxer- Obrir i desar fitxers amb diàlegs natius del sistema operatiu
from tkinter import messagebox as tkmb
from tkinter import simpledialog as tksd
from tkinter import filedialog as tkfd
file_path = tkfd.askopenfilename(
title='Selecciona un fitxer',
filetypes=[('Text', '*.txt'), ('Secret', '*.secret')]
)
password = tksd.askstring('Contrasenya', 'Introdueix la contrasenya:')
tkmb.showinfo('Desat', f'Fitxer desat correctament')
Video 6 — Menú i mida de lletra¶
tk.Menuper crear la barra de menú principaladd_cascade,add_command,add_separatorper estructurar el menúadd_checkbuttoniadd_radiobuttonper a opcions dins del menú- Menús en cascada (submenús) amb
add_cascade - Canvi de mida de lletra del
Textambconfigure(font=...)
menu = tk.Menu(root)
root.configure(menu=menu)
file_menu = tk.Menu(menu, tearoff=0)
menu.add_cascade(label='Fitxer', menu=file_menu)
file_menu.add_command(label='Obre', command=open_file)
file_menu.add_command(label='Desa', command=save)
file_menu.add_separator()
file_menu.add_command(label='Surt', command=root.destroy)
size_menu = tk.Menu(options_menu, tearoff=0)
for size in range(6, 33, 2):
size_menu.add_radiobutton(label=size, value=size, variable=font_size)
Video 7 — Radiobutton i estructura avançada¶
Radiobuttonper triar una opció d'un grup (variable compartida)packper disposar widgets horitzontalment dins d'un frame- Afegir marca de data/hora al missatge en desar
- Subframe general del formulari per millorar el layout
datestamp_var = tk.StringVar(value='None')
datestamp_frame = tk.Frame(form_frame)
for value in ('None', 'Date', 'Date+Time'):
tk.Radiobutton(
datestamp_frame,
text=value,
value=value,
variable=datestamp_var
).pack(side=tk.LEFT)
Video 8 — ttk: widgets amb tema i Notebook¶
El mòdul tkinter.ttk proporciona widgets amb estil natiu del sistema operatiu.
ttk.Notebook: contenidor de pestanyes navegablesttk.Frame,ttk.Label,ttk.Entry,ttk.Button,ttk.Checkbutton,ttk.Radiobuttonttk.Comboboxcom a alternativa millorada aOptionMenuttk.Separatorper separar seccions visualmentttk.Treeviewper mostrar dades en format taula amb columnes ordenables
from tkinter import ttk
notebook = ttk.Notebook(root)
notebook.grid(sticky='nesw', padx=5, pady=5)
notebook.enable_traversal()
form_frame = ttk.Frame(notebook)
notebook.add(form_frame, text='Entrada del diari', underline=0)
files_frame = ttk.Frame(notebook)
notebook.add(files_frame, text='Fitxers', underline=0)
# Treeview amb columnes
file_tree = ttk.Treeview(files_frame)
ft_columns = ('Nom', 'Tipus', 'Creat')
file_tree.configure(columns=ft_columns, show='headings')
Video 9 — ttk.Style: personalització visual i temes¶
ttk.Styleper definir l'aparença dels widgets ttkstyle.configure('TLabel', font=...)per estilitzar per tipus de widgetstyle.map(...)per canviar l'estil segons l'estat (selected, active, disabled)- Estils personalitzats com
'Status.TLabel' style.theme_names()per llistar els temes disponiblesstyle.theme_use(theme)per canviar el tema en temps d'execució
style = ttk.Style()
style.configure('TLabel', font='Arial 18 bold')
style.configure('TCheckbutton', font='Arial 16 bold', background='silver')
style.configure('Status.TLabel', font='Arial 12', background='white')
style.map(
'TCheckbutton',
background=[
('selected', 'pink'),
('active', 'red'),
('disabled', 'grey')
]
)
# Canviar tema dinàmicament
theme_var = tk.StringVar()
theme_var.trace_add('write', lambda *a: style.theme_use(theme_var.get()))
Instal·lació¶
Tkinter ve inclòs amb Python. En algunes distribucions Linux cal instal·lar-lo per separat:
Execució dels exemples¶
Llicència¶
Tot el codi d'aquest repositori està llicenciat sota la llicència MIT.