Développer une interface web avec le toolkit Atlas (2/2)

Posté par  (site Web personnel) . Édité par orfenor, Pierre Jarillon, Benoît Sibaud et Ysabeau. Modéré par Ysabeau. Licence CC By‑SA.
Étiquettes :
15
27
jan.
2021
Python

Le toolkit Atlas permet de programmer des interfaces d’applications web monopages (SPA) sans qu’il ne soit nécessaire de savoir programmer en JavaScript et sans imposer d’architecture logicielle. De plus, toute application développée avec le toolkit Atlas est, dès son lancement, instantanément et automatiquement accessible d’Internet.
Le toolkit Atlas s’apparente à ces bibliothèques qui, en s’appuyant sur GTK, Qt, wxWidgets…, ont pour but de faciliter le développement d’interfaces graphiques. La différence est que le toolkit Atlas, lui, s’appuie sur les technologies web (HTML/CSS).

Le toolkit Atlas est disponible pour Java, Node.js, Perl, Python et Ruby. Ce document porte sur le développement, avec la version Python du toolkit Atlas, d’une application dont voici un aperçu :

Apparence de l’application faisant l’objet du tutoriel 'Contacts'

Sommaire

Précédemment dans Développer une interface web avec le toolkit Atlas

Sur les recommandations de l’équipe de modération, ce document a été découpé en deux dépêches, dont voici la seconde.

La précédente dépêche présentait le fichier HTML principal, celui des métadonnées, ainsi que les principales fonctions relatives à l’affichage. Cette seconde dépêche va porter sur la gestion des évènements dédiés à l’édition.

Désactivation des champs + bouton New (part4.py)

  • Code source : lien sur GitHub ;
  • exécution :
    • sur Repl.it : bouton Run, n4 + entrée, clic sur URL,
    • en local : python3 atlas-python/tutorials/Contacts/part4.py

On remarquera que le contenu des champs dans lesquels s’affichent les détails sont modifiables, ce qui n’est pas le comportement voulu dans ce contexte. On va donc écrire le code permettant de désactiver ces champs.

Champs à désactiver

Pour cela, on va d’abord créer une liste contenant les identifiants, définis dans le fichier Main.html, des différents champs à désactiver :

FIELDS = [
  "Name",
  "Address",
  "Phone",
  "Note"
]

Gestion générale des éléments interactifs

On va créer une fonction qui va gérer l’état de ces champs, et qui sera complétée ultérieurement pour gérer d’autres éléments :

def update_outfit(dom):
  dom.disable_elements(FIELDS)

Cette fonction fait appel à la méthode disable_elements(…), dont le rôle est de désactiver les éléments dont les identifiants sont passés en paramètres.

On va également utiliser cette fonction pour faire apparaître le bouton New, qui permet de saisir un nouveau contact.
Pour cela, on a affecté la classe Display à ce bouton (voir le fichier Main.html). Comme l’élément style d’identifiant HideDisplay (voir le fichier Head.html) définit la règle qui cache les éléments de classe Display, on va le désactiver en utilisant la méthode disable_element(…). La fonction update_outfit(…) se présente alors de la manière suivante :

def update_outfit(dom):
  dom.disable_elements(FIELDS)
  dom.disable_element("HideDisplay")

On pourrait également ajouter l’identifiant HideDisplay à la liste passée à disable_elements(…), pour économiser un appel de fonction.

Mise en œuvre

On va appeler cette fonction à chaque action de l’utilisateur, ce qui peut sembler ne pas être approprié vu son contenu actuel, mais prendra sens avec la version finale de cette fonction, que l’on découvrira par la suite :

def ac_connect(dom):
  dom.inner("",open("Main.html").read())
  display_contacts(dom)
  update_outfit(dom)

def ac_select(dom,id):
  display_contact(int(id),dom)
  update_outfit(dom)

Saisie d’un nouveau contact (part5.py)

  • Code source : lien sur GitHub ;
  • exécution :
    • sur Repl.it : bouton Run, n5 + entrée, clic sur URL,
    • en local : python3 atlas-python/tutorials/Contacts/part5.py

On va maintenant gérer l’action affectée au bouton New. Pour cela, on va utiliser un objet qui va stocker le mode (state dans le code source) dans lequel est placé le logiciel, à savoir édition ou affichage.

Les différents modes de l’application

On va d’abord créer un enum relatifs à ces deux modes, à l’aide du module enum, que l’on va importer en modifiant l’instruction d’importation existante :

 import atlastk, enum

Créons l'enum proprement dit :

class State(enum.Enum):
  DISPLAY = enum.auto() # Affichage
  EDIT = enum.auto()    # Édition

Classe dédiée à chaque session

On va maintenant créer une classe Board dans laquelle on va pouvoir stocker les différentes variables propres à chaque session :

class Board:
  def __init__(self):
    self.state = State.DISPLAY

Le constructeur de cette classe (__init__(…)) va stocker le mode initial de l’application, à savoir DISPLAY (affichage), dans la variable membre state.

Il faudra créer une instance de cette classe pour chaque nouvelle session. Ceci est réalisé automatiquement par le toolkit Atlas : il suffit de modifier l’appel à la fonction launch(…) en remplaçant le paramètre de valeur None par le constructeur de cette classe, ce qui donne :

atlastk.launch(CALLBACKS,Board,open("Head.html").read())

Ce faisant, toutes les fonctions référencées dans CALLBACKS, qui, je le rappelle, contient les associations entre fonctions et actions, vont recevoir l’instance de l’objet Board correspondant à la session à l’origine de l’appel. Il faut donc modifier le prototype de ces fonctions :

def ac_connect(board,dom):
  

def ac_select(board,dom,id):
  

Notez l’ajout du paramètre board.

Adaptation de la gestion des contrôles interactifs

On va passer ce paramètre à la fonction update_outfit(…), pour qu’on puisse y tenir compte du mode dans lequel se trouve l’application et agir en conséquence, ce qui donne :

def update_outfit(board,dom):
  if board.state == State.DISPLAY:
    dom.disable_elements(FIELDS)
    dom.disable_element("HideDisplay")
  elif board.state == State.EDIT:
    dom.enable_elements(FIELDS)
    dom.enable_elements("HideDisplay")

On y utilise les méthodes enable_element[s](…), qui sont les pendants des méthodes disable_element[s](…).

Autres adaptations

Il faut, bien entendu, également modifier les appels à update_outfit(…) en conséquence ; on va également, par précaution, mettre à jour, dans l’instance board, le mode de l’application pour être sûr qu’il correspond à l’action lancée :

def ac_connect(board,dom):
  
  board.state = State.DISPLAY
  update_outfit(board,dom)


def ac_select(board,dom,id):
  
  board.state = State.DISPLAY
  update_outfit(board,dom)

On va également modifier la fonction display_contact(…), pour pouvoir l’utiliser afin de vider le contenu des champs. Pour cela on va créer un dictionnaire correspondant à un contact vide :

EMPTY_CONTACT = {
  "Name": "",
  "Address": "",
  "Phone": "",
  "Note": ""
}

qui va être utilisé de la manière suivante dans la fonction display_contact(…) :

def display_contact(contactId,dom):
  dom.set_values(EMPTY_CONTACT if contactId == None else contacts[contactId])

On notera que donner la valeur None au paramètre contactId entraînera dorénavant le vidage des champs.

Activation de la saisie

Ne reste plus qu’à définir la fonction qui sera appelée lors d’un clic sur le bouton New :

def ac_new(board,dom):
  board.state = State.EDIT
  display_contact(None,dom)
  update_outfit(board,dom)
  dom.focus("Name")

Cette fonction réalise successivement les opérations suivantes :

  • stockage dans l’instance de l’objet board du nouveau mode du logiciel, à savoir EDIT (édition) ;
  • vidage des champs de saisie ;
  • mise à jour de l’apparence de l’interface ;
  • affectation du focus (méthode focus(…)) au premier champ éditable (d’identifiant Name, qui correspond au champ contenant le nom affecté au contact), de manière à ce que l’utilisateur puisse procéder immédiatement à la saisie du nouveau contact.

N’oublions pas d’associer cette fonction à l’action idoine :

CALLBACKS = {
  
  "New": ac_new
 }

Boutons de saisie (part6.py)

  • Code source : lien sur GitHub ;
  • exécution :
    • sur Repl.it : bouton Run, n6 + entrée, clic sur URL,
    • en local : python3 atlas-python/tutorials/Contacts/part6.py

On peut maintenant saisir un nouveau contact, mais il manque les boutons pour valider ou annuler cette saisie.

Adaptation de la gestion des contrôles interactifs

Pour afficher les boutons Submit et Cancel, on va désactiver l’élément style d’identifiant HideEdition (voir le fichier Head.html). Cet élément définit une règle permettant de cacher les éléments auxquels on a affecté la classe Edition, comme c’est le cas de l’élément div contenant les deux boutons Submit et Cancel (voir le fichier Main.html).
Désactiver cet élément style pour faire apparaître les boutons d’éditions ne suffit pas ; il faut également l’activer pour cacher ces boutons lorsque requis. On va, pour cela, modifier la fonction update_outfit(…) afin d’obtenir cela :

def update_outfit(board,dom):
  if board.state == State.DISPLAY:
    dom.disable_elements(FIELDS)
    dom.disable_element("HideDisplay")
    dom.enable_element("HideEdition")
  elif board.state == State.EDIT:
    dom.enable_elements(FIELDS)
    dom.enable_element("HideDisplay")
    dom.disable_element("HideEdition")

Confirmation/annulation d’une saisie

Maintenant que les boutons sont affichés, on va créer les fonctions associées.

Pour le bouton Cancel, on va demander confirmation de l’annulation et, en fonction de la réponse, ne rien faire, ou repasser en mode d’affichage après avoir vidé les champs de saisie :

def ac_cancel(board,dom):
  if dom.confirm("Are you sure?"):
    display_contact(None,dom)
    board.state = State.DISPLAY
    update_outfit(board,dom)

La méthode confirm(…) ouvre une boîte de dialogue affichant la chaîne de caractères passée en paramètre. Elle retourne True lorsque l’on clique sur le bouton OK (ou ce qui en tient lieu), ou False si on clique sur le bouton Cancel (ou ce qui en tient lieu), tout en fermant ladite boîte de dialogue.

Pour le bouton Submit, il s’agit de récupérer les valeurs des champs de saisie, de stocker lesdites valeurs dans ce qui tient lieu de base de donnée, à savoir la variable contacts, de rafraîchir la liste des contacts, et de rebasculer en mode saisie, tout cela sous condition que le champ Name contienne une valeur :

def ac_submit(board,dom):
  idsAndValues = dom.get_values(FIELDS)

  if not idsAndValues['Name'].strip():
    dom.alert("The name field can not be empty!")
  else:
    board.state = State.DISPLAY
    contacts.append(idsAndValues)
    display_contact(None,dom)
    display_contacts(dom)
    update_outfit(board,dom)

La méthode get_values(…) prend une liste de chaînes de caractères correspondants à des identifiants d’éléments, et retourne un dictionnaire avec, pour clefs, ces identifiants, et, pour valeurs, le contenu de ces éléments. Comme les identifiants sont identiques aux clefs d’un contact, ou peut stocker le dictionnaire obtenu tel quel.

La méthode alert(…) affiche simplement une boîte de dialogue contenant, comme message, la chaîne passée en paramètre, avec un bouton OK (ou équivalent) permettant de la fermer.

On termine en mettant à jour CALLBACKS pour affecter ces nouvelles fonctions aux actions adéquates :

CALLBACKS = {
  
  "Cancel": ac_cancel,
  "Submit": ac_submit
}

Les autres boutons (part7.py)

  • Code source : lien sur GitHub ;
  • exécution :
    • sur Repl.it : bouton Run, n7 + entrée, clic sur URL,
    • en local : python3 atlas-python/tutorials/Contacts/part7.py

Il nous reste deux boutons à gérer : le bouton d’édition (Edit) et le bouton de suppression (Delete).

Adaptation de la classe Board

Avant toute chose, nous allons modifier la classe Board pour lui ajouter une variable (contactId) stockant l’index, dans la liste, du contact sélectionné. Cette variable est mise à None lorsqu’aucun contact n’est sélectionné :

class Board:
  def __init__(self):
    self.state = State.DISPLAY
    self.contactId = None

Nous allons également modifier ac_select(…) pour gérer cette nouvelle variable :

def ac_select(board,dom,id):
  board.contactId = int(id)
  display_contact(board.contactId,dom)
  

Adaptation de la gestion des contrôles interactifs

La variable ajoutée à la classe Board va également nous servir pour l’affichage des boutons manquants.
La classe DisplayAndSelect est affectée à ces boutons (voir le fichier Main.html), dont la règle CSS pour cacher les éléments de cette classe est définie dans l’élément style d’identifiant HideDisplayAndSelect (voir le fichier Head.html).

On obtient donc cela :

def update_outfit(board,dom):
  if board.state == State.DISPLAY:
    
    if board.contactId == None:
      dom.enable_element("HideDisplayAndSelect")
    else:
      dom.disable_element("HideDisplayAndSelect")
  elif board.state == State.EDIT:
    
    dom.enable_elements(("HideDisplay","HideDisplayAndSelect"))
    

Modification d’un contact

Passons à la fonction qui sera associée au bouton Edit. Elle reprendra en grande partie le contenu de la fonction ac_new(…) (on pourrait d’ailleurs en factoriser une partie) :

def ac_edit(board,dom):
  board.state = State.EDIT
  display_contact(board.contactId,dom)
  update_outfit(board,dom)
  dom.focus("Name")

Il faut aussi modifier la fonction ac_submit(…), pour tenir compte de son exécution dans le cadre de la modification d’un contact :

def ac_submit(board,dom):
  
  else:
    board.state = State.DISPLAY
    if board.contactId == None:
      contacts.append(idsAndValues)
    else:
      contacts[board.contactId] = idsAndValues
    display_contact(board.contactId,dom)
    display_contacts(dom)
    

Et également la fonction ac_cancel(…) pour la même raison :

  if dom.confirm("Are you sure?"):
    display_contact(board.contactId,dom)
    board.state = State.DISPLAY
    update_outfit(board,dom)

Et mettons à jour CALLBACKS :

CALLBACKS {
  
  "Edit": ac_edit
}

Suppression d’un contact

Implémentons maintenant la fonction qui sera associée au bouton Delete, qui ne présente rien de particulier, au regard de ce qui a été abordé dans les précédentes sections :

def ac_delete(board,dom):
  contacts.pop(board.contactId)
  board.contactId = None;
  display_contact(None,dom)
  display_contacts(dom)
  update_outfit(board,dom)

Et mettons à jour CALLBACKS :

CALLBACKS {
  
  "Delete": ac_delete
}

Bonus (part8.py)

  • Code source : lien sur GitHub ;
  • exécution :
    • sur Repl.it : bouton Run, n8 + entrée, clic sur URL,
    • en local : python3 atlas-python/tutorials/Contacts/part8.py

Comme vous avez pu le constater, la variable contacts est globale. Cela a pour conséquence qu’elle est commune à toutes les sessions. Cependant, une modification apportée à cette variable par une session n’est pas immédiatement visible dans toutes les autres sessions.
L’objet de cette section est d’apporter les modifications au code pour remédier à cela.

On va se limiter à rafraîchir, dès qu’une modification y est apportée, l’affichage de la liste des contacts dans l’ensemble des sessions.

Pour commencer, on va créer une fonction qui va rafraîchir la liste des contacts :

def ac_refresh(board,dom):
  display_contacts(dom)

Elle présente des similitudes, concernant les paramètres qu’elle reçoit, avec les fonctions associées à des actions (ac_edit(…), ac_submit(…)…). Cela n’a rien d’étonnant, car on va effectivement l’associer à une action :

CALLBACKS = {
  
  "Refresh": ac_refresh
}

Et maintenant, on va remplacer, dans les fonctions qui modifient la liste des contacts, à savoir ac_submit(…) et ac_delete(…), chaque appel à la fonction display_contacts(dom) par un appel à atlastk.broadcast_action("Refresh").

def ac_submit(board,dom):
  
    display_contact(board.contactId,dom)
    atlastk.broadcast_action("Refresh")
    update_outfit(board,dom)


def ac_delete(board,dom):
  
  display_contact(None,dom)
  atlastk.broadcast_action("Refresh")
  update_outfit(board,dom)

atlastk.broadcast_action(…) lance l’action dont le libellé est passé en paramètre dans toutes les sessions, ce qui, en l’occurrence, va provoquer l’appel à la fonction display_contacts(…), et ainsi la liste des contacts sera rafraîchie dans toutes les sessions.

Le fait que la variable contacts soit globale, et donc modifiable par toutes les sessions, nécessiterait d’écrire du code supplémentaire, notamment pour en contrôler l’accès. De par l’absence de ce code, il est facile de mettre cette application en défaut. Néanmoins, ce code ne concernant pas directement le toolkit Atlas, il sort du cadre de ce document, et ne sera donc pas abordé ici.

Vers l’infini, et au-delà !

Dans le dépôt GitHub, et donc également présents sur Repl.it, on trouvera, en plus des fichiers sources correspondant aux différentes sections de ce document, un certain nombre d’exemples permettant d’explorer différents aspects du toolkit Atlas. En outre, comme déjà évoqué, le toolkit Atlas est disponible pour d’autres langages que Python.
Bien que seule la version Python soit vraiment utilisée, j’envisage de développer d’autres versions du toolkit Atlas. Histoire de faire un peu de veille technologique, ça sera probablement une version Rust et/ou Go.
Dans l’intervalle, de nouvelles fonctionnalités seront rendues disponibles, ainsi que, peut-être, de nouveaux documents comme celui-ci, ou encore de nouvelles bibliothèques s’appuyant sur le toolkit Atlas, à l’instar des bibliothèques EduTK (création d’exercices de programmation d’un nouveau genre) (dépêche), term2web (redirection de l’entrée et de la sortie standard dans un navigateur web) (journal) ou encore tortoise (la tortue du Logo dans un navigateur web) (journal)…

Aller plus loin

  • # JustPy

    Posté par  . Évalué à 6 (+4/-0). Dernière modification le 27/01/21 à 17:02.

    Un peu basé sur le même concept, on retrouve JustPy.
    Il integer les composants Quasar et Highchart.

    L'idée consiste à déporter la moindre action qu'on effectuerait sur le client en JS, coté serveur, en ne transférant que les données par Websocket.

    Pour ce dernier, c'est sympa pour prototyper rapidement mais j'ai quelques doutes sur le passage à l'échelle.

    Hormis le fait que l'interface est en mode déclaratif, en quoi Atlas est-il différent, notamment en terme d'architecture ?

    Belle initiative cependant.

    • [^] # Re: JustPy

      Posté par  . Évalué à 2 (+1/-0).

      Je ne connais pas JustPy, mais cela semble comparable à Phoenix LiveView (Phoenix est un framework web pour Elixir). Le peu que j'en ai fait m'a pas mal bluffé, et la montée en charge ne semble pas poser de problème.

      Après, Elixir tournant sur BEAM, je pense que cela aide un peu (le modèle acteur est vraiment chouette), je ne sais pas ce qu'il en serait avec Python.

      https://www.phoenixframework.org/

    • [^] # Re: JustPy

      Posté par  (site Web personnel) . Évalué à 4 (+2/-0).

      Un peu basé sur le même concept, on retrouve JustPy.
      Il integer les composants Quasar et Highchart.

      J'ai un peu regardé JustPy, que je ne connaissais pas du tout. Je ne connais pas non plus Quasar et Highchart mais, vu les similitudes entre JustPy et le toolkit Atlas, il doit y avoir moyen de les intégrer également, ou du moins de les gérer de la même façon que Matplotlib dans cet exemple : https://repl.it/@AtlasTK/atlas-python, clic sur bouton vert Run, taper o puis entrée, et clic sur l'URL affichée dans la console (code source : https://repl.it/@AtlasTK/atlas-python#examples/MatPlotLib/main.py)…

      L'idée consiste à déporter la moindre action qu'on effectuerait sur le client en JS, coté serveur, en ne transférant que les données par Websocket.

      C'est effectivement la même idée qu'il y a derrière le toolkit Atlas.

      Pour ce dernier, c'est sympa pour prototyper rapidement mais j'ai quelques doutes sur le passage à l'échelle.

      Je ne sais pas pour JustPy, mais, pour le toolkit Atlas, la facilité de mise en œuvre et d'utilisation a été privilégiée à la performance, sachant qu'il y a déjà une multitude de frameworks, surtout web, qui offrent d'excellentes performances.
      J'utilise la technologie qu'il y a derrière le toolkit Atlas pour l'interface web de certains logiciels métiers que j'ai développés pour mes clients et, dans ce contexte, les performances sont largement suffisantes.

      Hormis le fait que l'interface est en mode déclaratif, en quoi Atlas est-il différent, notamment en terme d'architecture ?

      Le toolkit Atlas s'appuie sur un serveur. Il reçoit de ce dernier les actions réalisées par l'utilisateur, et lui retourne des primitives (inspirées de l'API DOM) correspondants aux modifications à apporter à l'interface. C'est ce qui fait que le toolkit Atlas est très léger et n'a pas de dépendances, puisqu'il n'embarque que de quoi communiquer avec le serveur, les primitives étant traitées par ce dernier. En outre, grâce à cette architecture, contrairement à JustPy et autres frameworks web, l'application n'a pas à être déployée pour être accessible d'Internet. On peut bien sûr également utiliser son propre serveur, le code source de ce dernier étant publié sous licence libre.

      Belle initiative cependant.

      Merci !

      Le toolkit Atlas, la bibliothèque légère et facile à utilser pour débuter avec la programmation d'interfaces graphiques… (voir 'site Web personnel").

      • [^] # Re: JustPy

        Posté par  . Évalué à 3 (+1/-0). Dernière modification le 28/01/21 à 19:27.

        Merci pour ta réponse, cependant j'ai peur de ne pas avoir saisi cette partie:

        Le toolkit Atlas s'appuie sur un serveur. Il reçoit de ce dernier les actions réalisées par l'utilisateur, et lui retourne des primitives (inspirées de l'API DOM) correspondants aux modifications à apporter à l'interface. C'est ce qui fait que le toolkit Atlas est très léger et n'a pas de dépendances, puisqu'il n'embarque que de quoi communiquer avec le serveur, les primitives étant traitées par ce dernier.

        Il me semble que c'est aussi le cas de JustPy pour du pur html. Simplement pour Quasar, il offre d'autres primitives en sus pour couvrir ses composants:
        https://justpy.io/quasar_tutorial/introduction/

        En outre, grâce à cette architecture, contrairement à JustPy et autres frameworks web, l'application n'a pas à être déployée pour être accessible d'Internet. On peut bien sûr également utiliser son propre serveur, le code source de ce dernier étant publié sous licence libre.

        Idem pas sûr de comprendre. Déployer sur un serveur WSGI ? Il faut bien un serveur d'app pour faire tourner des pages dynamiques. JustPy aussi embarque son propre serveur.

        Ravi d'apprendre que ca tourne en prod. Il faudra que je teste ça un jour.

        • [^] # Re: JustPy

          Posté par  (site Web personnel) . Évalué à 2 (+0/-0). Dernière modification le 29/01/21 à 18:58.

          J'ai relu mon commentaire, et il y a effectivement quelques raccourcis, involontaires, qui ne facilitent pas la compréhension. Cependant, je crains de ne pouvoir te répondre précisément, car il y a des aspects du fonctionnement de JustPy et des composants sur lesquels il s'appuie qui m'échappent encore. Néanmoins, je vais donner quelques précisions sur le fonctionnement du toolkit Atlas, en espérant que cela apporte tout de même quelques éléments de réponse…

          Concernant le poids des paquets respectifs, j'ai récupéré les données suivantes sur Pypi.org :

          • taille du paquet :
            • JustPy : ~4 Mo,
            • toolkit Atlas : ~20 Ko ;
          • paquets installés en sus :
            • JustPy : starlette, uvicorn, itsdangerous, websockets…,
            • toolkit Atlas : aucun.

          Les différences entre JustPy et le toolkit Atlas proviennent du fait que, avec JustPy, tout ce qui est nécessaire à son fonctionnement est rapatrié sur et exécuté par la machine du développeur, alors que, dans le cas du toolkit Atlas, le gros du traitement est déporté sur un serveur, auquel se connecte le toolkit.

          Voici un petit schéma qui, j'espère, clarifie cela :

          Titre de l'image

          xdhqxdh est une bibliothèque dynamique chargée par xdhwebq. xdhqxdh relaie les évènements associés aux actions de l'utilisateur vers le toolkit Atlas, et, en retour, traduit les primitives envoyées par ce dernier en opérations sur le DOM à destination du navigateur web. xdhwebq permet d'exécuter xdhqxdh dans un environnement web, sachant qu'il existe un équivalent permettant de l'exécuter dans un environnement bureau (interface desktop).

          Il y a donc deux serveurs, l'un est un serveur web classique (Apache, NGINX…), et l'autre est constitué par le couple xdhwebq/xdhqxdh, mais le développeur n'a à installer aucun des deux, le toolkit Atlas se connectant automatiquement par défaut à un serveur public que je mets gratuitement à disposition. C'est pour cela qu'une application développée avec le toolkit Atlas est automatiquement et instantanément accessible de tout l'internet via l'URL affichée dans la console à son lancement…

          Si tu as d'autres question concernant le toolkit Atlas, que ce soit sur son fonctionnement ou des problèmes que tu aurais rencontrés dans sa mise en œuvre, n'hésite pas. Ça me donnera matière à enrichir la documentation, qui en a bien besoin…

          Le toolkit Atlas, la bibliothèque légère et facile à utilser pour débuter avec la programmation d'interfaces graphiques… (voir 'site Web personnel").

          • [^] # Re: JustPy

            Posté par  . Évalué à 2 (+0/-0).

            C'est plus clair en effet. Tu rajoutes un niveau d'indirection pour éviter au développeur de gérer une partie du déploiement, le routing, … et offrir un genre de cloud providing. Une sorte de serverless pour tout ce concerne l'IHM en quelque sorte.

            Intéressant. Je comprends l'intérêt pour pouvoir le conjuguer avec du natif, mais dans ton cas on a besoin d'ouvrir des ports TCP et si le serveur "métier", celui du dev, est déporté la latence doit s'en ressentir, non ?

            Ne serait-il pas judicieux d'offrir en plus le support du websocket à ce niveau selon qu'on se trouve sur le même réseau ou sur l'internet. Ou si tu décidais d'hoster proposer du déploiement de la partie métier.

            Tu expliques aussi qu'Atlas est multi-language. Ceci signifie t'il que tu l'as implémenté dans tous ces languages ou que tu passe par un wrapper ?

            • [^] # Re: JustPy

              Posté par  (site Web personnel) . Évalué à 3 (+1/-0).

              Le toolkit Atlas a d'abord été développé pour Java, Node.js et PHP (cette dernière version n'est plus disponible à cause de problèmes concernant le multithreading), et s'appuyait sur du code natif développé en C++. Mais la présence de code natif complexifie énormément l'installation, ce qui peut décourager ceux qui étaient tentés de l'essayer.

              Du coup, j'ai développé dans chacun des langages pour lequel le toolkit était disponible, puis ensuite en Perl, Python et Ruby, des fonctionnalités permettant de déporter tout le code natif sur un serveur. En fait, le toolkit Atlas, en l'état, est une version de démonstration d'une technologie que j'ai baptisée XDHTML et qui permettra, à terme, de coder avec des technos web, mais sans JavaScript (sauf pour la version Node.js), une interface graphique web, desktop et/ou mobile.

              Ce qui a été implémenté dans chacun des langages pour lequel le toolkit est disponible, c'est juste le protocole permettant de communiquer avec le proxy. À terme, le proxy existera également sous forme de bibliothèque dynamique directement chargée par l'application utilisant le toolkit Atlas, et cette dernière communiquera alors avec le proxy, non plus via une connexion réseau, mais en appelant directement les fonctions natives du proxy. De ce fait, il n'y aura plus de problèmes de latence.

              Le toolkit Atlas, la bibliothèque légère et facile à utilser pour débuter avec la programmation d'interfaces graphiques… (voir 'site Web personnel").

  • # PySimpleGUI et Remi

    Posté par  . Évalué à 2 (+1/-0).

    J'ai découvert récemment PySimpleGUI et je suis vraiment conquis. Moi qui ai eu du mal à rentrer dans tous les autres toolkits / frameworks pour faire des interfaces graphiques, je prends enfin du plaisir à faire des boutons et autres fenêtres.

    Je n'ai pas testé spécifiquement mais PySimpleGUI permet de générer la "même" interface graphique (au calage des éléments près) avec des back-ends tkinter (que j'utilise), QT, WxWidgets ou HTML, pour ce dernier via Remi (que je ne connaissais pas non plus).

    Le projet est relativement jeune (créé en 2018) mais extrêmement prometteur je trouve, surtout pour l'encapsulage de petits scripts en remplacement des macros Excel, autrement dit le même cas d'usage que pour Atlas.

    Je n'ai pas trouvé de journal ou de dépêche sur ce cadriciel, mais il faudrait sans doute y remédier. Je vais tenter d'initialiser quelque chose en espace de rédaction.

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n’en sommes pas responsables.