Comme avec tous les autres "frameworks", le contrôle du flux dans les applications wxWidgets est basé sur les événements.
Le programme effectue normalement la plupart de ses actions en réponse aux événements générés par l'utilisateur.
Ces événements peuvent être déclenchés en utilisant un périphérique d'entrée tel que clavier, souris, joystick, directement ou par un contrôle standard comme par exemple un wxButton.
Il y a aussi des événements qui ne correspondent pas directement à l'action de l'utilisateur, tels que wxTimerEvent ou wxSocketEvent.
Depuis la version 2.9.0 de Widgets, il existe deux façons principales de gérer les événements dans wxWidgets.
Or, les tables d'évènements statiques ne peuvent gérer les évènements que dans l'objet où il est défini.
C'est l'une des raisons pour lesquelles wxWidgets recommande d'utiliser la gestion dynamique.
Mais, la gestion dynamique des évènements, n'est apparue qu'à partir de la version 2.9.0 de wxWidgets et celle utilisée par wxLua est la 2.8.10.
Par conséquent, nous n'aborderons dans ce document que la gestion dite "statique", celle utilisant les macros des tables d'évènements.
L'utilisation du "wrapper" wxLua, facilite grandement la gestion des évènements et nous dispense du tout travail préparatoire qui est indispensable avec d'autres langages de programmation.
Chaque classe va donc émettre un certain nombre d'évènements, qui seront gérés par les macros appropriées.
Il suffit de déclarer les gestionnaires d'évènements que vous souhaitez utiliser dans votre code, de la façon suivante:
nomObjet:Connect(ID, macro, nomFonction) --et pour être un peu plus précis, par exemple, nomObjet:Connect(wx.wxID_OPEN, wx.wxEVT_xxx, nomFonction) --ou dans le cas ou il n'y aurait pas ID.. nomObjet:Connect(wx.wxEVT_xxx, nomFonction)
La fonction qui va traiter les évènements est appellée "callback" chez nos amis anglophones.
L'évènement est d'abord soumis à l'objet qui en est l'émetteur. Il est ensuite transmis à la fonction que vous lui avez associée et qui traitera l'évènement.
frame:Connect(wx.wxID_OPEN, wx.wxEVT_COMMAND_MENU_SELECTED, OnOpenFile)
Vous remarquerez qu'aucun paramètre n'est transmis et qu'il ne faut pas écrire par exemple:
OnOpenFile(), mais OnOpenFile tout simplement et sans parenthèse.
Chaque classe émettera donc un certain nombre d'évènements, qui seront gérés par les macros appropriées.
Qu'entendons-nous, par "propagation des évènements?
Cela signifie, que l'évènement, qui est à la recheche de la fonction qui lui est associée, a la posibilité de passer de la fenêtre-enfant à la fenêtre-parent... jusqu'à ce qu'il ait trouvé ce qu'il cherche.
Mais seuls, les évènements de type wxCommandEvent, qui regroupent toutes les actions sur les contrôles, les éléments de menus ou les barres d'outils, bref les actions directes de l'utilisateur ont la faculté de se propager de la fenêtre-enfant vers la fenêtre-parent.
En fin de compte, si l'évènement ne rencontre pas sa fonction dédiée au travers de l'enfant puis du parent, il aboutira à l'objet wxApp (qui est le parent de tous les objets de l'application) et obtiendra ainsi une dernière chance d'être traité.
Dans les boîtes de Dialogues toutefois, les évènements ne se propagent pas jusqu'à l'objet WxApp, ils s'arrêtent à l'objet wxDialog.
Il n'y a pas de propagation pour tous les autres types d'évènements ( fermeture ou redimensionnement de fenêtre, appui de touche, évènement "souris", etc.), mais on peut également la forcer en surchargeant la méthode ProcessEvent de l'objet considéré.
La déclaration d'une fonction personnalisée pour un évènement, occulte le traitement qu'un contrôle assure par défaut, et qu'il est parfois souhaitable de conserver. Il suffit pour ce faire d'appeler la méthode wxEvent:Skip à la fin de la fonction. Il est ainsi possible de programmer un comportement spécifique pour une wxListCtrl pour gérer les appuis sur certaines touches du clavier, tout en conservant la navigation traditionnelle par les touches Home, End,PageUp,PageDown.
Ci-dessous, quelques exemples de code sur l'utilisation des évènements sous wxWidgets avec wxLua.
- Evènements liés aux contôles |
nomObjet:Connect(ID, wx.wxEVT_CHOICE, NomFonction) Clic dans une case à cocher |
nomObjet:Connect(ID, wx.wxEVT_BUTTON, NomFonction) Clic sur un bouton classique |
nomObjet:Connect(ID, wx.wxEVT_MENU, NomFonction) Choix d'un élément de menu |
- Événements liés au comportement de la fenêtre |
nomObjet:Connect(wx.wxEVT_CLOSE, NomFonction) Clic sur la petite croix de fermeture de fenêtre |
nomObjet:Connect(wx.wxEVT_SIZE, NomFonction) L'utilisateur a redimensionné la fenêtre |
nomObjet:Connect(wx.wxEVT_MOVE, NomFonction) L'utilisateur a déplacé la fenêtre |
- Événements liés au clavier et à la souris |
nomObjet:Connect(wx.wxEVT_CHAR, NomFonction) Une touche clavier a été pressée et relâchée |
nomObjet:Connect(wx.wxEVT_MOTION, NomFonction) Déplacement de la souris |
Le principe est toujours le même: nomObjet:Connect( ID, MACRO, FONCTION )
Les macros relatives à chaque évènement de classe, sont définies dans la documentation wxWidgets.
Et pour une approche plus complète sur les évènements, je vous recommande de lire dans le manuel de référence wxWidgets: "Events and Events Handling"...