Cours Apl 11
Introduction à la gestion des écrans
Dyalog Apl vous permet de créer les écrans de 2 manières compatibles :
- à la souris, comme dans la plupart des langages (via le ws wdesign),
- en écrivant des fonctions qui construisent et/ou modifient les écrans. C'est cette voie que nous allons explorer.
Quelques notions préliminaires
- Objet : on appelle objet une fenêtre, un bouton, une zone de liste, ...- Propriété : une propriété défini les caractéristiques d'un objet telles que sa taille, sa couleur, son contenu, son libellé, son nom, ...
- Evènement : Il peut arriver diverses choses à un objet du fait de l'utilisateur du programme.
Par exemple, dans le cas d'un bouton, il peut être cliqué, enfoncé, relâché, être survolé par la souris, ce qui nous fait déjà 4 évènements.
A quoi servent les évènements ?
Lorsqu'un évènement précis se produit, on veut déclencher une action.Par exemple, si on clique sur un bouton intitulé "Enregistrer", on lance une fonction qui enregistrera le travail.
- Méthode : On peut assimiler une méthode à une fonction de l'objet auquel elle appartient.
Par exemple, dans le cas de l'objet Grid (tableur Apl), il existe une méthode AddRow qui permet d'ajouter des lignes.
Une méthode est appelée par un programme alors qu'un évènement résulte généralement d'une action de l'utilisateur.
Premiers objets et propriétés
L'objet de base est la fenêtre : FormElle a un certain nombre de propriétés dont le type de l'objet, un libellé, un emplacement et une taille.
Pour créer un objet window, on utilise la fonction système ⎕WC (window create).
L'argument gauche est le nom que portera l'objet et l'argument droit contient les propriétés de l'objet.
Maintenant passons à l'action.
Nous allons créer notre première fenêtre qui s'appellera F1.
'F1' ⎕WC 'Form' ('Caption' 'Multiplication')('Size' 50 50)Vous trouverez une nouvelle icône dans la barre des tâches. Si vous cliquez dessus, vous verrez apparaître une fenêtre vide, dont le titre sera "Multiplication", occupant la moitié de l'écran.
Ajoutons deux zones de saisie avec leurs libellés à cet écran.
D'abord, le libellé :
'F1.L1' ⎕WC 'Label' 'Série de nombres' ('Posn' 10 5)('Size' ⍬ 25)- A chaque fois qu'on crée un objet, on doit respecter la syntaxe suivante :
'objet_père.nouvel objet' ⎕WC 'Type d'objet' ('nom_propriété 1' valeur(s)_propriété 1) ('nom_propriété 2' valeur(s)_propriété 2)- Les propriétés ont toutes un emplacement par défaut. Ainsi, on peut directement indiquer la valeur d'une propriété sans en mentionner le nom, si on la place au bon endroit.
- Type d'objet
Tous les objets ont pour première propriété leur type. C'est pourquoi on l'indique immédiatement après le ⎕WC sans préciser un nom de propriété.
On peut également définir le type ailleurs qu'en 1ère position. Dans ce cas, il faudra écrire un couple ('Type' 'Form') pour une fenêtre.
- 'Label' signifie que F1.L1 est une étiquette.
C'est un objet ne pouvant contenir que du texte et dans lequel on ne peut pas saisir.
- 'Série de nombres' est le texte affiché. Le nom de cette propriété est 'Caption'. Pour un Label c'est toujours la deuxième propriété définie. Aussi, si on la met à cet endroit, il n'est pas obligatoire de mentionner le nom de la propriété définie.
- 'Posn' indique la position du coin supérieur gauche de l'objet par rapport au coin supérieur gauche de l'objet père. Par défaut ces coordonnées sont exprimées en pourcentage de la taille de l'objet père.
On indique toujours les coordonnées en hauteur puis largeur.
- 'Size' défini la taille de l'objet.
Par défaut, elle est également exprimée en pourcentage de la taille de l'objet père
('Size' ⍬ 25) signifie qu'on laisse Apl choisir la hauteur la plus appropriée et qu'on force la largeur à 25% de celle de F1.
Ajoutons maintenant le champ de saisie de la série de nombres :
'F1.S1' ⎕WC 'Edit' ('Posn' 10 40)('Size' ⍬ 50)Nouveau label et nouveau champ :
'F1.L2' ⎕WC 'Label' 'Coefficient : ' ('Posn' 30 5)('Size' ⍬ 25) 'F1.S2' ⎕WC 'Edit' ('Posn' 30 40)('Size' ⍬ 20)Affichage du résultat du calcul :
'F1.L3' ⎕WC 'Label' 'Résultat : ' ('Posn' 50 5)('Size' ⍬ 25) 'F1.S3' ⎕WC 'Edit' ('Posn' 50 40)('Size' 20 50)Bouton de lancement du calcul :
'F1.B1' ⎕WC 'Button' 'Calculer' ('Posn' 80 ⍬)('Size' ⍬ 50)Une fois tout ça saisi, vous devez avoir à l'écran votre nouvelle fenêtre :
En entrant ce code, vous avez créé un nouvel objet : F1
Si vous tapez ⎕NL 9, Apl vous répondra :
F1
⎕NL signifie 'Name List'. Il rend la liste des noms correspondant à la ou les classes données en argument droit.
⎕NL 2 rend la liste des variables et ⎕NL 3 la liste des fonctions.
⎕NL 9 rend la liste des namespaces et des objets graphiques.
Pour en savoir plus :
- aide en ligne
- ⎕NC : réciproque de ⎕NL, rend la classe de l'objet nommé en argument droit.
Pour l'instant l'écran existe mais il ne fait rien.
Effacez F1 en tapant :
)erase F1puis créez la fonction Mulvec, localisez F1 et reprenez les lignes de définition de l'écran dans la fonction.
Si vous lancez la fonction, il ne se passe rien, vous ne voyez rien à l'écran. C'est normal : l'écran est créé, mais comme il est localisé dans la fonction, il est détruit, dès qu'on en sort.
Pour que l'écran soit actif, vous devez "donner la main" à Windows.
C'est la fonction ⎕DQ qui s'en charge.
Elle active l'objet dont le nom est mentionné en argument droit.
Ajoutez cette ligne dans votre fonction et relancez-la :
⎕DQ 'F1'Listing de la fonction :
Mulvec;F1;CR 'F1'⎕WC'Form'('Caption' 'Multiplication')('Size' 50 50) 'F1.L1'⎕WC'Label' 'Série de nombres'('Posn' 10 5)('Size'⍬ 25) 'F1.S1'⎕WC'Edit'('Posn' 10 40)('Size'⍬ 50) 'F1.L2'⎕WC'Label' 'Coefficient : '('Posn' 30 5)('Size'⍬ 25) 'F1.S2' ⎕WC 'Edit' ('Posn' 30 40)('Size' ⍬ 20) 'F1.L3'⎕WC'Label' 'Résultat : '('Posn' 50 5)('Size'⍬ 25) 'F1.S3'⎕WC'Edit'('Posn' 50 40)('Size' 20 50) 'F1.B1'⎕WC'Button' 'Calculer'('Posn' 80 ⍬)('Size'⍬ 50) ⎕DQ'F1'L'écran s'affiche, on peut même saisir des valeurs mais pour l'instant aucun calcul ne s'effectue.
Pour quitter votre nouvel écran et revenir à APL, fermez la fenêtre en cliquant sur la croix en haut à droite.
C'est ici qu'interviennent les évènements.
Quand l'évènement "clic sur le bouton calculer" se produit, on veut que la multiplication soit effectuée et que le résultat soit affiché dans F1.S3
On a le choix entre 2 méthodes :
- soit on analyse le résultat du ⎕DQ dans la fonction Mulvec pour voir si le calcul a été demandé
- soit on appelle une fonction de traitement spécifique (fonction callback). Nous allons d'abord explorer cette voie.
Créez la fonction Mulvec_cal
Elle admet comme argument droit le compte rendu de l'événement ayant occasionné son appel.
Toute fonction callback possède au moins cet argument car APL l'appelle systématiquement en le lui passant et il est souvent utilisé, comme nous le verrons par la suite.
Entrez ces lignes dans la fonction :
Mulvec_cal d F1.S3.Text←⍕(⍎F1.S1.Text)×(⍎F1.S2.Text)La fonction exécute ⍎, exécute la chaîne de caractères qui lui est passée en argument droit. Dans le cas d'une chaîne de caractères contenant uniquement des numériques, elle rend un ou plusieurs nombres (plusieurs si ils sont séparés par des espaces ou des virgules) et la fonction format ⍕ convertit un ou plusieurs nombres en chaîne de caractères.
Le contenu d'un champ texte correspond à sa propriété 'Text' et ne peut être qu'une chaîne de caractères, même si elle n'est constituée que de chiffres. C'est pourquoi on formate le résultat du calcul avant de le mettre dans F1.S3.
De même, on ne peut multiplier que des chiffres, c'est pourquoi on numérise le contenu des champs S1 et S2.
Branchons maintenant notre fonction de calcul.
Nous devons donc dire à APL que quand le bouton B1 est actionné, on doit appeler la fonction Mulvec_cal.
Pour ce faire, nous allons modifier la ligne de définition du bouton comme suit :
'F1.B1'⎕WC'Button' 'Calculer'('Posn' 80 ⍬)('Size'⍬ 50)('Event' 'Select' 'Mulvec_cal')- Event signifie qu'on défini la propriété Evènement.
- Select est le nom de l'évènement correspondant au simple click sur un bouton
- Mulvec_cal est la fonction callback qui doit être appelée lorsque l∇évènement se produit.
Essayez à nouveau votre fonction.
Si les valeurs entrées ne sont pas correctes, la fonction Mulvec_cal va se planter. Pour éviter cela, on va gérer l'erreur avec le :Trap.
C'est un traitement conditionnel dont l'idée est : "si ça se passe bien, je fais ci, sinon je fais ça."
Nouveau texte de la fonction :
Mulvec_cal d :Trap 0 F1.S3.Text←⍕(⍎F1.S1.Text)×(⍎F1.S2.Text) :Else F1.S3.Text←'Erreur !' :EndTrapPour en savoir plus sur le :Trap consultez l'aide en ligne. On gère également les erreurs avec le ⎕Trap. Réessayez en saisissant des valeurs incorrectes.
Nous allons maintenant voir comment gérer les événements sans utiliser de fonction callback.
Commençons par remplacer la zone de saisie F1.S2 par un objet Spinner.
C'est une zone de saisie avec des flèches permettant d'en augmenter ou diminuer la valeur.
La valeur du coefficient pourra aller de -100 à 100.
Nous allons également demander à Apl de reprendre la main lorsqu'on clique sur une des flèches pour modifier la valeur du spinner afin de recalculer immédiatement le résultat avec le nouveau coefficient.
Remplacez la définition de F1.S2 par :
'F1.S2'⎕WC'Spinner'('Posn' 30 40)('Size'⍬ 40)('Event' 'Spin' 1)('Limits' ¯100 100)Remplacez également la dernière ligne de la fonction Mulvec par les suivantes :
ET_AFF:CR←⎕DQ 'F1' :If 0≠ ⍴CR F1.S2.Value←3⊃CR Mulvec_cal'' →ET_AFF :EndIfET_AFF: est une étiquette qui indique une ligne de la fonction.
:If 0≠⍴CR marque le début d'un bloc d'instructions exécutées uniquement si la taille de CR n'est pas nulle. En effet, si on ferme la fenêtre en cliquant sur la croix en haut à droite, CR reçoit un vecteur vide.
Si le test est concluant, on met le 3ème élément de CR (nouvelle valeur) dans F1.S2, on refait un calcul en appelant Mulvec_cal '' (l'argument n'a aucune importance puisqu'il n'est pas exploité par la fonction), et avec →ET_AFF on redonne la main à Windows.
Dans le respect des règles d∇hygiène des développeurs pas trop cochons, ajoutez CR à votre liste de variables locales.
Testez votre fonction.
Au cas où quelque chose ne fonctionnerait pas correctement, le texte complet de la fonction est :
Mulvec;F1;CR 'F1'⎕WC'Form'('Caption' 'Multiplication')('Size' 50 50) 'F1.L1'⎕WC'Label' 'Série de nombres'('Posn' 10 5)('Size'⍬ 25) 'F1.S1'⎕WC'Edit'('Posn' 10 40)('Size'⍬ 50) 'F1.L2'⎕WC'Label' 'Coefficient : '('Posn' 30 5)('Size'⍬ 25) 'F1.S2'⎕WC'Spinner'('Posn' 30 40)('Size'⍬ 40)('Event' 'Spin' 1)('Limits' ¯100 100) 'F1.L3'⎕WC'Label' 'Résultat : '('Posn' 50 5)('Size'⍬ 25) 'F1.S3'⎕WC'Edit'('Posn' 50 40)('Size' 20 50) 'F1.B1'⎕WC'Button' 'Calculer'('Posn' 80 ⍬)('Size'⍬ 50)('Event' 'Select' 'Mulvec_cal') ET_AFF:CR←⎕DQ'F1' :If 0≠⍴CR F1.S2.Value←3⊃CR Mulvec_cal'' →ET_AFF :EndIfPour en savoir plus sur les objets graphiques mis à votre disposition dans Dyalog Apl, il existe 2 tutoriels très riches :
- Wtutor
- Wtutor95
Chargez les et explorez tout, c'est simple, efficace et vraiment beau.
Pour les passionnés de graphiques, allez faire un tour du coté du workspace Rain.
Sinon, il y a toujours l'aide en ligne.