FAQ Tkinter #
Widgets de base #
Les petits programmes qui suivent sont tous fonctionnels. En règle générale, les variables qui sont accédées à plusieurs endroits du programme sont stockées dans un dictionnaire, de manière à n’avoir finalement qu’une seule variable globale.
Bouton #
import tkinter as tk
def bouton_cb():
print("Vous avez cliqué")
def gui(root):
frame = tk.Frame(root)
frame.pack(expand=1, fill='both')
open_button = tk.Button(frame, text="Bouton", command=bouton_cb)
open_button.pack(padx=8, pady=8)
root = tk.Tk()
gui(root)
root.mainloop()
Entry #
import tkinter as tk
g_entry = None # Variable globale
def entree_cb(ev):
print("Vous avez écrit : " + g_entry.get())
def gui(root):
global g_entry
frame = tk.Frame(root)
frame.pack(expand=1, fill='both')
g_entry = tk.Entry(frame)
g_entry.pack(padx=8, pady=8)
# Pour appeler une callback si on appuie sur Entrée :
g_entry.bind('<Return>', entree_cb)
root = tk.Tk()
gui(root)
root.mainloop()
OptionMenu #
import tkinter as tk
v_menu = None # Variable globale
def changement(*ev):
print("Choix :", v_menu.get())
def gui(root):
global var
global v_menu
liste_choix = ("Option 1", "Option 2", "Option 3")
frame = tk.Frame(root)
frame.pack(expand=1, fill=tk.BOTH)
# On associe une variable au menu
v_menu = tk.StringVar()
v_menu.set(liste_choix[0])
menu = tk.OptionMenu(frame, v_menu, *liste_choix)
# Appel d'une callback si la variable change
v_menu.trace('w', changement)
menu.pack(padx=8, pady=8)
#menu.place(x=10, y=10, width=300, height=80)
root = tk.Tk()
gui(root)
root.mainloop()
RadioButtons #
import tkinter as tk
def clicked():
print("Selection : {}".format(v.get()))
root = tk.Tk()
v = tk.IntVar()
v.set(2) # Permet de choisir le radiobutton coché par défaut
a = tk.Radiobutton(root, text="One", variable=v, value=1, command=clicked)
b = tk.Radiobutton(root, text="Two", variable=v, value=2, command=clicked)
a.pack()
b.pack()
root.mainloop()
Dialogues #
Boîte de sélection de fichier #
import tkinter as tk
from tkinter import filedialog
import os.path
def choosefile():
result = filedialog.askopenfilename(initialdir="C:\\")
print("RESULT", result, type(result))
def gui(root):
frame = tk.Frame(root)
root.title("Exemple ouverture fichier")
frame.pack(expand=1, fill='both')
open_button = tk.Button(frame, text="Ouvrir fichier", command=choosefile)
open_button.pack(padx=8, pady=8)
root = tk.Tk()
gui(root)
root.mainloop()
Événements #
Tester le type d’événement #
La callback suivante est appelée si on appuie sur une touche du clavier ou si on clique avec le bouton gauche de la souris. Comment différencier le type d’événement qui a eu lieu ?
import tkinter as tk
def handler(ev):
print(ev)
print(ev.type) # contient un nombre
if ev.type == tk.EventType.KeyPress: # évite de mettre des valeurs numériques
print("Clavier")
elif ex.type == tk.EventType.Button:
print("Souris"
else:
print("Autre événement")
Utiliser la même callback sur plusieurs objets avec partial #
partial
permet, à partir d’une fonction prenant des paramètres, d’en
créer une nouvelle avec certains paramètres fixés.
#!/usr/bin/env python3
import tkinter as tk
import functools
def connect(texte):
print("Vous avez cliqué sur ", texte)
# =====================================================
# Fenêtre principale
# =====================================================
class Fenetre(tk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.master.title("Fenêtre principale")
self.pack(fill='both', expand=1)
for text in "ABCD":
temp_bouton = tk.Button(self, width=10, height=1, text=text,
command=functools.partial(connect, texte="BOUT-{}".format(text)))
temp_bouton.pack()
# Création de l'application
root = tk.Tk()
# Ajout des éléments graphiques
gui = Fenetre(root)
# Boucle des événements
root.mainloop()
Widgets complexes #
Intégration d’un graphe Matplotlib dans une application tkinter
#
Voici un exemple de code qui intègre un graphe dans une fenêtre tkinter
.
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import random
from matplotlib.figure import Figure
import tkinter as tk
def plot(canvas, figure):
if figure.axes:
figure.delaxes(figure.axes[0])
axes = figure.add_subplot(111)
x = range(1,10)
axes.plot(x, [random.random() for _ in x])
canvas.draw()
def create_ui():
root = tk.Tk()
root.wm_title("Embedding in TK")
root.geometry("500x500")
frame = tk.Frame(master=root)
frame.pack(fill=tk.BOTH, expand=1)
figure = Figure(figsize=(5, 4), dpi=100)
axes = figure.add_subplot(111)
canvas = FigureCanvasTkAgg(figure, master=frame)
canvas.draw()
canvas.get_tk_widget().place(x=10, y =40, width=400, height=400)
label = tk.Label(master=frame, text="Le Beau Graphe")
label.place(x=10, y=10, width=100, height=30)
# Utilisation d'une fermeture, les valeurs de canvas et figure sont capturées
button = tk.Button(master=frame, text='update', command=lambda: plot(canvas, figure))
button.pack(side=tk.BOTTOM)
return root
root = create_ui()
root.mainloop()
Boîte de dialogue (login/pass) modale avec tkinter #
#!/usr/bin/env python3
import tkinter as tk
# =====================================================
# Fenêtre de connexion
# =====================================================
# Doit hériter de Toplevel pour être une fenêtre séparée
# http://effbot.org/tkinterbook/toplevel.htm
class LoginDialog(tk.Toplevel):
def __init__(self, parent):
super().__init__(parent)
self.title("Fenêtre Modale")
# ---------------------------------------
tk.Label(self, text="Login : ").pack()
self.entry_login = tk.Entry(self)
self.entry_login.insert(0, "defaultlogin")
self.entry_login.pack()
# ---------------------------------------
tk.Label(self, text="Clé : ").pack()
self.entry_pass = tk.Entry(self, show='*')
self.entry_pass.insert(0, "defaultpass")
self.entry_pass.pack()
# ---------------------------------------
tk.Button(self, text="Connexion", command=self.connect).pack()
def connect(self):
login = self.entry_login.get().strip()
key = self.entry_pass.get().strip()
print("Informations entrées : ", login, key)
self.destroy()
def connect():
""" Ouvre une fenêtre modale """
result = LoginDialog(root)
result.transient(root)
result.grab_set()
root.wait_window(result)
# =====================================================
# Fenêtre principale
# =====================================================
class Fenetre(tk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.master.title("Fenêtre principale")
self.pack(fill='both', expand=1)
bouton_new = tk.Button(self, width=10, height=1, text="Connexion", command=connect)
bouton_new.pack()
# Création de l'application
root = tk.Tk()
# Ajout des éléments graphiques
gui = Fenetre(root)
# Boucle des événements
root.mainloop()