2009-02-06 3 views
8

Ich bin Prototyping einer Python-App mit dem cmd-Modul.Paginierung mit dem Python-Cmd-Modul

Einige Nachrichten an den Benutzer werden ziemlich lang sein und ich möchte sie paginieren. Die ersten 10 Zeilen (oder eine konfigurierbare Nummer) der Nachricht werden angezeigt, und durch Drücken der LEERTASTE wird die nächste Seite bis zum Ende der Nachricht angezeigt.

Ich möchte hier nichts neu erfinden, gibt es ein einfaches Mittel, um diese Funktion zu implementieren?

Antwort

4

Die einfache Sache wäre nur, Ihr Skript zur Laufzeit durch "weniger" oder einen ähnlichen Befehl zu leiten.

Hier ist ein einfaches Verfahren, das tut, etwa, was Sie wollen, aber:

def print_and_wait(some_long_message): 
    lines = some_long_message.split('\n') 
    i=0 
    while i < len(lines): 
     print '\n'.join(lines[i:i+10]) 
     raw_input("press enter to read more...") 
     i += 10 

Sie auch in mit Flüche aussehen könnte.

+0

Vielen Dank, aber die Durchleitung durch weniger würde die Interaktion verhindern, was das Ziel des cmd-Moduls ist. Die Implementierung einer curses-Lösung geht weit über den ersten Entwurf hinaus, den ich mit dem cmd-Modul erstellen möchte. Ihre print_and_wait-Lösung ist jedoch ein guter Anfang (funktionierte nicht so wie es ist). – Gra

3

Wie Yoni oben gesagt hat, besteht der richtige Weg darin, eine Druckmethode bereitzustellen, die automatisch in Ihrer laufenden cmd-Instanz paginiert. Der Konstruktor von Cmd übernimmt die Argumente stdin und stdout. Stellen Sie einfach ein Objekt bereit, das wie stdout funktioniert und Ihre Paging-Druckmethode unterstützt.

class PagingStdOut(object): 
    def write(self, buffer, lines_before_pause=40): 
     # do magic paging here... 
0

Paging-Subroutinen in der genutils.py Datei von IPython (siehe page oder page_dumb für einen einfacheren) gefunden werden. Der Code ist ein wenig kompliziert, aber das ist wahrscheinlich unvermeidbar, wenn Sie versuchen, zu Systemen einschließlich Windows und den verschiedenen Arten von Terminalemulatoren portierbar zu sein.

+0

Danke, ich habe bereits meine Paging-Routinen implementiert. Ich werde nachsehen, was ich in den Dateien verpasst habe. Derzeit funktioniert es in meinem Betriebssystem, aber ich habe nichts anderes getestet, daher könnten die portablen Erweiterungen nützlich sein. – Gra

1

Ich hatte die gleiche Frage. In der pydoc module ist ein Pager eingebaut. Ich habe es so eingebaut (was ich hackisch und unbefriedigend finde ... Ich bin offen für bessere Ideen).

Ich mag die Idee, dass es autopage würde, wenn es mehr als x Ergebnisse und Paging gibt, ist es möglich zu implementieren, aber nicht hier getan.

import cmd 
from pydoc import pager 
from cStringIO import StringIO 
import sys 

PAGER = True 
class Commander(cmd.Cmd): 
    prompt = "> " 
    def do_pager(self,line): 
     global PAGER 
     line = line + " 1" 
     tokens = line.lower().split() 
     if tokens[0] in ("on","true","t", "1"): 
      PAGER = True 
      print "# setting PAGER True" 
     elif tokens[0] in ("off","false","f","0"): 
      PAGER = False 
      print "# setting PAGER False" 
     else: 
      print "# can't set pager: don't know -> %s" % tokens[0] 

    def do_demo(self,line): 
     results = dict(a=1,b=2,c=3) 
     self.format_commandline_results(results) 

    def format_commandline_results(self,results): 
     if PAGER: 
      ofh = StringIO() 
     else: 
      ofh = sys.stdout 

     for (k,v) in sorted(results.items()): 
      print >> ofh, "%s -> %s" % (k,v) 

     if PAGER: 
      ofh.seek(0) 
      pager(ofh.read()) 

     return None 

    def do_EOF(self,line): 
     print "", 
     return True 

if __name__ == "__main__": 
    Commander().cmdloop("# try: \n> pager off \n> demo \n> pager on \n> demo \n\n")