Gestion de la souris et du clavier¶
La bibliothèque fltk fournit pour l’instant des commandes simples permettant uniquement de gérer les clics de souris ou l’appui sur les touches du clavier. La gestion du clavier et de la souris peut se faire au moyen de la boucle suivante:
from fltk import *
cree_fenetre(400,400)
while True:
ev = donne_ev()
tev = type_ev(ev)
# Code traitant l'évènement
...
mise_a_jour()
ferme_fenetre()
À intervalles réguliers, ce programme récupère avec la fonction
donne_ev()
le premier événement qui s’est produit sur la
fenêtre depuis le dernier appel à cette fonction, ou un événement vide
indiquant l’absence d’un autre événement. Cette fonction renvoie en fait un
objet représentant un événement, comme par exemple un clic droit au point
de coordonnées (50,50).
Si ev
est un tel objet, l’appel type_ev(ev)
renvoie une chaîne
de caractères représentant le type de l’événement ev
. Il y a six
principaux types d’événements :
'Touche'
lorsque l’événement est un appui sur une touche ;'ClicGauche'
lorsque l’événement est un clic gauche ;'ClicDroit'
lorsque l’événement est un clic droit ;'Redimension'
lorsque l’événement est un redimensionnement de la fenêtre ;'Quitte'
lorsque l’événement est un clic sur le bouton de fermeture de la fenêtre ;None
lorsqu’il ne s’est rien passé.
Exemple : On souhaite écrire un petit programme ouvrant une fenêtre et affichant sur le terminal chaque événement qui se produit au cours de l’exécution. Voici une première tentative :
from fltk import *
cree_fenetre(400, 400)
while True:
# On récupère le plus ancien événement en attente
ev = donne_ev()
# On affiche son type
print(type_ev(ev))
Ce programme ne fonctionne pas, et affiche très rapidement et un grand
nombre de fois None
. Ceci est dû au fait que, quand aucun événement ne
s’est encore produit, la fonction donne_ev()
renvoit le résultat
None
. La version ci-dessous n’affiche que les vrais événements.
from fltk import *
cree_fenetre(400, 400)
while True:
# On récupère le plus ancien événement en attente
ev = donne_ev()
# S'il ne vaut pas None, on affiche son type
if ev is not None:
print(type_ev(ev))
Lorsqu’on teste ce programme, on se rend compte que la fenêtre semble « figée », et qu’aucun événement ne s’affiche. Le problème est qu’on a oublié de mettre à jour la fenêtre, ce qui a pour autre effet que les événements ne sont pas détectés. Le programme ci-dessous affiche correctement le type de tous les événements qui se produisent :
from fltk import *
cree_fenetre(400, 400)
while True:
# On récupère le plus ancien événement en attente
ev = donne_ev()
# S'il ne vaut pas None, on affiche son type
if ev is not None:
print(type_ev(ev))
# Important : on met à jour pour détecter les nouveaux événements
mise_a_jour()
Cet exemple fonctionne mieux, mais ne permet pas de fermer la fenêtre
correctement. Pour cela, on va sortir de la boucle quand on rencontre
un événement de type 'Quitte'
, et fermer la fenêtre à l’aide de
ferme_fenetre()
:
from fltk import *
cree_fenetre(400, 400)
while True:
# On récupère le plus ancien événement en attente
ev = donne_ev()
# S'il ne vaut pas None, on affiche son type
if ev is not None:
print(type_ev(ev))
# Si l'événement est de type 'Quitte', on sort de la boucle
if type_ev(ev) == 'Quitte':
break
# Important : on met à jour pour détecter les nouveaux événements
mise_a_jour()
# Le dernier événement était 'Quitte', on ferme la fenêtre
ferme_fenetre()
Avertissement
Pour que les frappes au clavier soient prises en compte, il faut que la fenêtre ait le focus, c’est à dire qu’elle soit active.
Nous allons maintenant voir comment traiter les événements récupérés.
Événement 'Touche'
¶
Lorsque l’événement ev
est de type 'Touche'
, on peut utiliser la
fonction touche()
qui renvoie une chaîne de caractères donnant le
nom de la touche qui a été pressée. Le programme ci-dessous affiche le nom de
toutes les touches pressées.
from fltk import *
cree_fenetre(400, 400)
while True:
ev = donne_ev()
tev = type_ev(ev)
# Action dépendant du type d'événement reçu :
if tev == 'Touche': # on indique la touche pressée
print('Appui sur la touche', touche(ev))
elif tev == 'Quitte': # on sort de la boucle
break
else: # dans les autres cas, on ne fait rien
pass
mise_a_jour()
ferme_fenetre()
Par exemple, on peut voir que:
la touche
A
a pour nom'a'
la barre d’espace a pour nom
'space'
la flèche droite a pour nom
'Right'
la flèche gauche a pour nom
'Left'
la flèche du haut a pour nom
'Up'
la flèche du bas a pour nom
'Down'
Le programme suivant permet de déplacer un carré sur la fenêtre avec les flèches.
from fltk import *
def carre(x, y, cote):
rectangle(x, y, x + cote, y + cote,
"red", "red", tag='carre')
cree_fenetre(400, 400)
# dessin initial du carré
cx, cy, taille = 0, 0, 10
carre(cx, cy, taille)
# déplacement en pixels à chaque flèche pressée
dep = 5
while True:
ev = donne_ev()
tev = type_ev(ev)
# déplacement du carré
dx = 0
dy = 0
if tev == 'Quitte':
break
if tev == 'Touche':
nom_touche = touche(ev)
if nom_touche == 'Left':
dx = max(-dep, -cx)
elif nom_touche == 'Right':
dx = min(dep, 399 - cx - taille)
elif nom_touche == 'Down':
dy = min(dep, 399 - cy - taille)
elif nom_touche == 'Up':
dy = max(-dep, -cy)
if dx != 0 or dy != 0:
efface('carre')
cx = cx + dx
cy = cy + dy
carre(cx, cy, taille)
mise_a_jour()
ferme_fenetre()
Événement 'ClicDroit'
ou 'ClicGauche'
¶
Pour connaitre les coordonnées correspondant à un evenement de
type 'ClicDroit'
ou 'ClicGauche'
, on utilise les
fonctions abscisse()
et ordonnee()
.
Par exemple, le programme suivant affiche les coordonnées des points cliqués.
from fltk import *
cree_fenetre(400, 400)
while True:
ev = donne_ev()
tev = type_ev(ev)
# Action dépendant du type d'événement reçu :
if tev == 'Touche':
print('Appui sur la touche', touche(ev))
elif tev == "ClicDroit":
print("Clic droit au point", (abscisse(ev), ordonnee(ev)))
elif tev == "ClicGauche":
print("Clic gauche au point", (abscisse(ev), ordonnee(ev)))
elif tev == 'Quitte': # on sort de la boucle
break
else: # dans les autres cas, on ne fait rien
pass
mise_a_jour()
ferme_fenetre()
Événement 'Redimension'
¶
Cet événement se produit quand la fenêtre est redimensionnée. Pour connaître
les nouvelles dimensions de la fenêtre, on utilise les fonctions
hauteur_fenetre()
et largeur_fenetre()
.
Par exemple, le programme suivant dessine un quadrillage 3 x 3 sur la fenêtre et le redessine dynamiquement lorsque la fenêtre est redimensionnée.
from fltk import *
nb_cases = 3
def dessine_quadrillage(largeur: int, hauteur: int, n: int):
texte(largeur/2, hauteur/2,
f"Taille de la fenêtre : {hauteur} x {largeur}",
ancrage='c')
hauteur_case = hauteur / n
largeur_case = largeur / n
x_courant = y_courant = 0.
for i in range(1, n):
x_courant += largeur_case
ligne(x_courant, 0, x_courant, hauteur)
y_courant += hauteur_case
ligne(0, y_courant, largeur, y_courant)
if __name__ == "__main__":
l_init = 600
h_init = 400
cree_fenetre(l_init, h_init, redimension=True)
dessine_quadrillage(l_init, h_init, nb_cases)
while True:
ev = attend_ev()
tev = type_ev(ev)
if tev == "Quitte":
ferme_fenetre()
break
elif tev == 'Redimension':
efface_tout()
dessine_quadrillage(largeur_fenetre(), hauteur_fenetre(), nb_cases)
elif tev == 'Touche':
tch = touche(ev)
if tch == 'plus':
larg = largeur_fenetre() * 1.2
haut = hauteur_fenetre() * 1.2
redimensionne_fenetre(larg, haut)
elif tch == 'minus':
larg = largeur_fenetre() / 1.2
haut = hauteur_fenetre() / 1.2
redimensionne_fenetre(larg, haut)
Liste des fonctions¶
- fltk.donne_ev() Optional[Tuple[str, Optional[Event]]] ¶
Renvoie immédiatement l’événement en attente le plus ancien, ou
None
si aucun événement n’est en attente.
- fltk.type_ev(ev: Optional[Tuple[str, Optional[Event]]]) Optional[str] ¶
Renvoie une chaîne donnant le type de
ev
. Les types possibles sont “ClicDroit”, “ClicGauche”, “Touche” et “Quitte”. RenvoieNone
sievenement
vautNone
.
- fltk.attente(temps: float) None ¶
- fltk.attend_ev() Tuple[str, Optional[Event]] ¶
Attend qu’un événement ait lieu et renvoie le premier événement qui se produit.
- fltk.attend_clic_gauche() Tuple[int, int] ¶
Attend qu’un clic gauche sur la fenêtre ait lieu et renvoie ses coordonnées. Attention, cette fonction empêche la détection d’autres événements ou la fermeture de la fenêtre.
- fltk.attend_fermeture() None ¶
Attend la fermeture de la fenêtre. Cette fonction renvoie None. Attention, cette fonction empêche la détection d’autres événements.
- fltk.abscisse(ev: Optional[Tuple[str, Optional[Event]]]) Optional[int] ¶
Renvoie la coordonnée x associé à
ev
si elle existe, None sinon.
- fltk.ordonnee(ev: Optional[Tuple[str, Optional[Event]]]) Optional[int] ¶
Renvoie la coordonnée y associé à
ev
si elle existe, None sinon.
- fltk.abscisse_souris() int ¶
- fltk.ordonnee_souris() int ¶
- fltk.touche(ev: Optional[Tuple[str, Optional[Event]]]) str ¶
Renvoie une chaîne correspondant à la touche associé à
ev
, si elle existe.
- fltk.touche_pressee(keysym: str) bool ¶
Renvoie True si
keysym
est actuellement pressée.Cette fonction est utile pour la gestion des touches de déplacement dans un jeu car elle permet une animation mieux maîtrisée, en évitant le phénomène de répétition de touche lié au système d’exploitation.
- Paramètres:
keysym – symbole associé à la touche à tester.
- Renvoie:
True si
keysym
est actuellement pressée, False sinon.