vendredi 31 juillet 2015

NPyScreen: interface en mode texte (console) pour Python

Dans l'article "urwid: interface en mode texte (console) pour Python" je regrettais surtout la lourdeur du Framework et la difficulté d'utilisation de celui-ci.

Je me penche donc sur une autre alternative "NPyScreen" en espérant que celle-ci ne soit pas tout aussi inapprochable qu'Urwid.

Basé sur nCurse, nPyScreen permet de réaliser des interfaces au look rudimentaires mais efficace.
NB: Depuis, je sais qu'il y a des thèmes et j'ai vraiment apprécié le temps (et investissement) très court pour la prise en main. I <3 nPyScreen.


Il faut avouer que le code correspondant est assez explicite.
Pour ma part, je préfère un code un peu plus long mais plus explicite.
La lisibilité (et le sens des instruction) est limpide, c'est déjà une bonne choses.

import npyscreen
class TestApp(npyscreen.NPSApp):
    def main(self):
        # These lines create the form and populate it with widgets.
        # A fairly complex screen in only 8 or so lines of code - a line for each control.
        F  = npyscreen.Form(name = "Welcome to Npyscreen",)
        t  = F.add(npyscreen.TitleText, name = "Text:",)
        fn = F.add(npyscreen.TitleFilename, name = "Filename:")
        fn2 = F.add(npyscreen.TitleFilenameCombo, name="Filename2:")
        dt = F.add(npyscreen.TitleDateCombo, name = "Date:")
        s  = F.add(npyscreen.TitleSlider, out_of=12, name = "Slider")
        ml = F.add(npyscreen.MultiLineEdit,
               value = """try typing here!\nMutiline text, press ^R to reformat.\n""",
               max_height=5, rely=9)
        ms = F.add(npyscreen.TitleSelectOne, max_height=4, value = [1,], name="Pick One",
                values = ["Option1","Option2","Option3"], scroll_exit=True)
        ms2= F.add(npyscreen.TitleMultiSelect, max_height =-2, value = [1,], name="Pick Several",
                values = ["Option1","Option2","Option3"], scroll_exit=True)

        # This lets the user interact with the Form.
        F.edit()

        print(ms.get_selected_objects())

if __name__ == "__main__":
    App = TestApp()
    App.run()

Voyez également la vidéo suivante présentant les différentes fonctionnalités de NPyScreen.

_curses.error: must call initscr() first

L'exemple le plus simple de npyscreen est celui-ci
MyForm = Form()

usrn_box = MyForm.add_widget(TitleText, name="Your name:")
internet = MyForm.add_widget(TitleText, name="Your favourite internet page:")

MyForm.edit()

et débouche inévitablement sur l'erreur:

_curses.error: must call initscr() first

La raison est simple, npyscreen se base sur la bibliothèque curse. Comme l'exemple n'initialise pas un objet "PyScreen Application" qui lui initialise Curse, nous devrons donc faire l'initialisation de Curse nous même.

Dans ce cas bien précis, il faudra faire l'initialisation de Curse nous même (voyez l'autre version de l'exemple.

Autre chose: une fois que curse est initialisé, il prend le contrôle totale de l'écran et de tout ce qui s'affiche.
Par conséquent, hors de question de taper le code de l'exemple dans un Python Interactif... dès que vous aurez initialisé Curse, vous ne verrez plus rien s'afficher à l'écran.
Il faut donc taper votre code dans un script Python puis exécuter le script Python.

#!/usr/bin/python
# encoding: utf8

import curses
from npyscreen import *

# Initialisation de curse
#   Non nécessaire si vous employez l'objet "PyScreen Application" pour
#   gérer l'application
curses.initscr()

# Exemple nPyScreen
MyForm = Form()

usrn_box = MyForm.add_widget( TitleText, name="Votre Nom" )
internet = MyForm.add_widget( TitleText, name="Your favorit internet page:" )

MyForm.edit()

# Remettre le terminal dans son état d'origine
curses.nocbreak()
curses.echo()
curses.curs_set( 1 )
curses.endwin()

# Imprimer les données collectées
print( 'Votre nom est %s' % usrn_box.value )
print( 'L adresse URI est %s' % internet.value )
 

Voici donc l'exemple complet et fonctionnel que nous avons placé dans le fichier 00_form.py que vous pouvez exécuter.

NPyScreen vs Urwid
Pour moi, il n'y a pas photo. 2H pour mon premier écran NPyScreen (avec le message d'erreur) contre 8H pour un résultat non satisfaisant (tellement il a été compliqué d'y arriver).

Pour mes petits outils de gestion journalier ce sera NPyScreen.

Ressources

Aucun commentaire: