CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[programmation GUI] Du code plus propre?

saleGauss
saleGauss
Niveau 9
03 juin 2010 à 01:15:20

Voila, je m'ennui un peu, et je voulais vous faire part d'une reflexion.

Depuis le temps où j'ai commencé à coder des interfaces graphiques pour des petits programmes (écrits par mes soins), je me suis rendu compte que le code de la partie GUI est toujours assez déguellasse.

Bon, les première fois, i s'agissait certes d'appli qui avaient été initialement pensées pour de la console.
Donc forcément, la GUI étant assez intrusive vu que c'est elle qui fait la "chef d'orchestre", en appelant mes fonctions au bons moments en fonction de ce que fais l'utilisateur, je me retrouvais avec un code assez imbuvable.

Et puis dans des projets plus récents (de fac essentiellement), je me suis rendu compte que même prévu à l'avance, le code d'une interface graphique me donne toujours l'impression d'être "rustiné".

C'est surement la nature même d'une GUI qui veut ça, dans le sens où se ne sont que des effets de bords.

Une autre question qui m'est apparue lié à ce sujet est la gestion de l'aspect "on empeche l'utilisateur de faire n'importe quoi".
Il y a toujours le moyen de gérer ça dans le GUI directement (exemple, je met sur ".setEnabled(false)" un bouton qu'il ne faut pas que l'utilisateur active à un certain moment.
Mais il serrait plus propre de faire quand même les vérifications dans la partie "algorithmique".
Que pensez vous de ce problème dans le cadre d'une discussion "sécurité du logiciel"?

Un autre problème : il m'arrive assez fréquemment d'écrire des programmes que je dois prouver. Ils sont prouvés soit à la main, soit à l'aide de l'Atelier B (et je dois donc me coltiner l'intégration d'une GUI sur un code C produit par l'atelier B à partir de ma spec et ma preuve).
Dans tous les cas, l'interface graphique vient perturber ma preuve.
Je peux foutre en l'air un programme qui doit être absolument fiable à cause d'un bouton que je n'ai pas remit sur ".enabled(true)".

Je me demandais comment pourrait être les API de création de GUI pour permettre :
1/ d'avoir le code de la GUI plus propre (moins d'effets "rustine")
2/ De concevoir une GUI n'ont plus comme un méchant machin à effet de bord, mais plus en terme fonctionnel. Le coté "effet de bord" ne devrait apparaitre qu'à la fin de la chaine, sans que le codeur de la GUI s'en préoccupe.
On pourrait peut-être envisager que une action sur un bouton ou un changement d'état soit une des sorties d'une fonction.
On pourrait aller plus loin et considérer que des fonctions livreraient le nouvel état d'un bouton en sortie, des fonctions "plus hautes" livreraient l'état d'une frame complète, et une fonction encore plus haute l'état de la GUI totale.
Un exemple, le créateur d'une GUI pourrait procéder ainsi :

let updateBoutonMachin = fun signal ->
match signal with
|... -> (resultat,nouveau_bouton)
|... -> (resultat2,nouveau_bouton2)
(* Calcule ce qu'il y a à calculer en fonction du signal, et renvoit le resultat et le nouvel état du bouton *)
;;

Bon, après je ne peux être plus précis sachant que je ne sais pas encore comment pourrait être représenté un bouton.
Dons l'updateFrame appellerait l'update sur tous les elements de la frame, l'updateGui sur toutes les frames de la GUI...
Et l'API de la GUI fournirait des fonctions du style :
'InitBouton = fun bouton'
Qui renvoit un bouton à partir d'un bouton "vierge"
Et une fonction
'SetHandler = fun ElementGraphique -> fun handler '
Qui permet d'associer un handler "UpdateBoutinMachin" au bouton en question.
Bref, je voudrais que l'état de la GUI soit plus "calculé"

3/ Pourquoi un état de la GUI plus calculé ?
Justement pour pouvoir plus facilement prouver que son état reste en permanence cohérent.
A l'heure actuelle, j'ai l'impression que de nombreux bugs d'applications ne sont que des bugs issu de la GUI, à cause d'un booléen pas remit en place.
Exemple, si l'utilisateur vient de sauvegarder, on le lui redemande pas immédiatement si il ferme l'appli.
Mais si après avoir refait une modif on a pas repensé à remettre le booléen "estSauvegarde" sur false, l'utilisateur va quitter sans que rien ne lui soit demandé.

Si l'état d'une GUI était moins "rustine un peu partout", il serait plus simple de prouver que "tant que la simulation est en cours, les boutons A, B et C sont dans tel état".

En fait, ce sont peut être aux assistants de preuve de programmes d'évoluer aussi.
Il faudrait qu'ils permettent plus facilement de manipuler des preuves sur des états d'éléments de GUI.

Voilà, je voulais vous faire part de cette reflexion et vous faire réagir dessus.
J'espère que les questions soulevées nous feront émerger de nouvelles idées.

A bientot

Paulop
Paulop
Niveau 12
03 juin 2010 à 02:21:42

C'est un bon pâté que tu nous as fait là :)

Je ne sais pas quel langage tu utilises, mais j'ai déjà eu l'occasion de faire des GUI en C# (pour XNA) en C++ et Lua.

J'ai utilisé un OOD dans les trois cas, mais d'autre design ne sont pas exclus.

Dans les trois cas, ma GUI est géré par une classe manager qui contient une list des contrôles à updater et afficher. On passe par le manager pour ajouter les contrôles et les supprimer.

Pour un bouton, tu fais un callback avec un pointeur de fonction, ou encore un delegate en C#. Quand tu ajoutes ton comportement, tu lui passes l'adresse de ta fonction, et quand tu clic dans le bouton, il callback la fonction.
De cette manière, c'est l'utilisateur qui code sa fonction et qui la link au bouton, tu ne gère que le comportement de ton bouton "quand je clic dedans, ça appelle mon callback". Bien entendu, tu vérifies bien que l'utilisateur a renseigné l'addresse de la fonction :)

J'espère avoir apporté des précisions.

_skip
_skip
Niveau 10
03 juin 2010 à 09:16:50

Bah pour moi c'est tout des problèmes qui peuvent être amoindris avec une adéquate séparation entre le métier et la présentation.

Le métier doit être une sortie d'API de haut niveau à disposition de la GUI qui n'est au final qu'un simple boîtier de commande. De ce fait, il devrait pouvoir être validé au moyen de tests unitaires sans recourir à la GUI.
Si ce n'est pas le cas (impossibilité de tester unitairement sans GUI) c'est déjà signe que ça peut pêcher dans l'architecture.

C'est aussi le rôle de l'API métier par exemple de détecter si une opération est invalide, style qqn veut supprimer un item mais n'a pas les droits suffisant.
Lorsqu'on se fie uniquement au fait que le bouton "supprimer" soit actif ou non c'est qu'on est en train de tout mélanger niveau responsabilité.

L'interface utilisateur qui grise/désactive des boutons doit être juste un confort supplémentaire, et cela doit être géré par la GUI.

La pire chose à faire dans une GUI, c'est de modifier l'état des contrôles à plein d'endroits style :

btnValidate_onClick()
{
...
btnEdit.Enabled = false;
}

btnInvalidate_onClick()
{
...
btnValidate.Enabled = true;
btnEdit.Enabled = true;
}

là ça devient le casse-tête et c'est la qu'on va oublier de changer un flag!
Le mieux c'est de tout faire dans une seule méthode :

void updateWndState( )
{
bool editEnabled = false;
bool validateEnabled = false;
bool invalidateEnabled = false;
bool deleteEnabled = false;
bool publishEnabled = false;

switch( itemState )
{
case : VALIDATED :
//un item validé peut être publié ou invalidé
invalidateEnabled = true;
publishEnabled = true;
break;

case : PENDING_VALIDATION
//un item en attente peut être supprimé ou validé
validateEnabled = true;
deleteEnabled = true;

....
}

//a la fin
btnDelete.setEnabled ( deleteEnabled);
btnPublish.setEnabled (publishEnabled);
...
}

Comme ça, il suffit d'appeler cette seule méthode pour s'assurer que l'affichage est consistent en l'état, ce qui limite les risques et facilite la relecture.

Une façon sympathique est d'avoir carrément au niveau de l'entité elle-même l'indication avec des méthodes métier :

bool item.canEdit();
bool item.canPublish();
bool item.canDelete();

Car ça rend également les disponibilités des actions testables unitairement.

dnob700
dnob700
Niveau 10
03 juin 2010 à 21:22:25

Je ne dirais qu'un seul mot : lablgtk

C'est l'interface GTK/OCaml. Qui est plus simple et plus agréable à utiliser que la version de GTK directement en C (bon je n'ai jamais fait de GTK directement, donc je ne peux pas comparer, mais c'est ce que tout le monde dit). Alors évidemment, il faut pondre pas mal de ligne de code, mais ça s'interface très bien au paradigme "fonctionnel". Je te conseille d'y jeter un oeuil.

saleGauss
saleGauss
Niveau 9
04 juin 2010 à 01:42:14

Merci pour vos remarques à tous.

Je vais donc aller très rapidement jetter un oeil du coté de lablgtk.

Sous forums
  • Aide à l'achat Mac
  • Steam Deck
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Macintosh
  • Hardware
La vidéo du moment