web-dev-qa-db-fra.com

Impression de terminal dynamique en python

Certaines applications telles que hellanzb ont une manière d’imprimer sur le terminal avec l’apparence d’un rafraîchissement dynamique des données, un peu comme top.

Quelle est la meilleure méthode en python pour le faire? J'ai lu sur la journalisation et les malédictions, mais je ne sais pas quoi utiliser. Je crée une réimplémentation de top. Si vous avez d'autres suggestions, je leur suis également ouvert. 

29
Recursion

Le moyen le plus simple, si vous n'avez jamais besoin de mettre à jour qu'une seule ligne (par exemple, en créant une barre de progression), consiste à utiliser '\r' (retour chariot) et sys.stdout:

import sys
import time

for i in range(10):
    sys.stdout.write("\r{0}>".format("="*i))
    sys.stdout.flush()
    time.sleep(0.5)

Si vous avez besoin d'une interface utilisateur de console appropriée prenant en charge le déplacement du pointeur, etc., utilisez le module curses de la bibliothèque standard:

import time
import curses

def pbar(window):
    for i in range(10):
        window.addstr(10, 10, "[" + ("=" * i) + ">" + (" " * (10 - i )) + "]")
        window.refresh()
        time.sleep(0.5)

curses.wrapper(pbar)

Il est vivement recommandé d’utiliser la fonction curses.wrapper pour appeler votre fonction principale, elle se chargera de nettoyer le terminal en cas d’erreur, afin qu’il ne soit plus inutilisable par la suite.

Si vous créez une interface utilisateur plus complexe, vous pouvez créer plusieurs fenêtres pour différentes parties de l'écran, des zones de saisie de texte et la prise en charge de la souris.

44
Torsten Marek

Comme la plupart des réponses l'ont déjà indiqué, vous n'avez vraiment aucune option sous Linux si vous utilisez ncurses. Mais que se passe-t-il si vous n'êtes pas sous Linux, ou si vous voulez quelque chose d'un peu plus haut niveau pour créer votre interface utilisateur de terminal?

J'ai personnellement trouvé frustrant l'absence d'API de terminal moderne multiplate-forme en Python, a donc écrit asciimatics pour résoudre ce problème. Non seulement cela vous donne un API simple multiplateforme , il fournit également beaucoup d'abstractions de niveau supérieur pour des widgets et des animations de l'interface utilisateur qui pourraient facilement être utilisés pour créer une interface de haut niveau.

13
Peter Brittain

Cela ressemble à un travail pour curses. C'est la bibliothèque la plus utilisée pour la disposition et la gestion des écrans en mode texte. Python supporte très bien les malédictions, y compris les panneaux:

2
gavinb

J'ai piraté ce script en utilisant curses. C'est vraiment une solution ad-hoc que j'ai faite pour s'amuser. Il ne prend pas en charge le défilement, mais je pense que c’est un bon point de départ si vous souhaitez créer un moniteur de mise à jour en direct avec plusieurs lignes sur le terminal.

https://Gist.github.com/tpandit/b2bc4f434ee7f5fd890e095e79283aec

1
tejas pandit

L'envoi d'une sortie au terminal via la commande print () peut être effectué sans défilement si vous utilisez l'attribut "end".

La valeur par défaut est end = '\ n', qui est une nouvelle ligne. 

Pour supprimer le défilement et écraser toute la ligne précédente, vous pouvez utiliser le retour d'échappement RETURN qui est '\ r'.

Si vous voulez seulement réécrire les quatre derniers caractères, vous pouvez utiliser quelques espaces arrière. 

print(value, "_of_", total, end='\r')

NOTE Ceci fonctionne pour le terminal système standard. L'émulateur de terminal dans certains outils comme IDLE a une erreur et le '\ r' ne fonctionne pas correctement, la sortie est simplement concaténée avec un caractère non imprimable entre. 

INFORMATIONS BONUS POUR print () Dans l'exemple ci-dessus, les espaces de chaque côté de "of" sont destinés à assurer un espace blanc entre mes valeurs et le mot "of". Cependant, le séparateur par défaut de print () est un "" (espace). Nous avons donc un espace blanc entre la valeur et le trait de soulignement de "_of_". 

>> print (value, "_of_", total, end='\r')
8 _of_ 17

L'attribut sepparator, sep, peut être utilisé pour définir le caractère entre les éléments imprimés. Dans mon exemple, je le changerai en une chaîne nulle ('') pour adapter ma sortie à mes besoins.

>> print (value, "_of_", total, sep='', end='\r')
8_of_17
0
GT Electronics

Lorsque je fais cela dans des scripts Shell sous Unix, j'ai tendance à utiliser simplement le programme clair. Vous pouvez utiliser le module de sous-processus Python pour l'exécuter. Au moins, vous obtiendrez rapidement ce que vous cherchez.

0
Omnifarious