2009-02-06 20 views
8

Sto prototipando un'applicazione Python con il modulo cmd.impaginazione con il modulo cmd python

Alcuni messaggi per l'utente saranno piuttosto lunghi e mi piacerebbe impaginarli. Verranno visualizzate le prime 10 righe (o un numero configurabile) del messaggio e premendo la barra SPACE verrà visualizzata la pagina successiva, fino alla fine del messaggio.

Non voglio reinventare qualcosa qui, c'è un mezzo semplice per implementare questa funzione?

risposta

4

La cosa più semplice sarebbe semplicemente passare lo script attraverso "less" o un comando simile in fase di esecuzione.

Ecco un metodo semplice che fa circa ciò che si vuole, però:

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 

Si potrebbe anche considerare di usare maledizioni.

+0

Grazie, tuttavia, il collegamento di un numero inferiore impedirà l'interazione, che è l'obiettivo del modulo cmd. L'implementazione di una soluzione di curses va ben oltre la prima bozza che voglio creare con il modulo cmd. Tuttavia la tua soluzione print_and_wait è un buon inizio (non ha funzionato come è). – Gra

3

Come detto in precedenza da Yoni, il modo corretto per eseguire questa operazione è fornire un metodo di stampa che pagine automaticamente all'interno dell'istanza di cmd in esecuzione. Il costruttore di Cmd accetta gli argomenti stdin e stdout. Così semplice fornire un oggetto che funziona come stdout e supporta il tuo metodo di stampa di paging.

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

subroutine paging possono essere trovati nel file genutils.py di IPython (vedi page, o page_dumb per uno più semplice). Il codice è un po 'complicato, ma questo è probabilmente inevitabile se si sta cercando di essere portabile a sistemi che includono Windows e vari tipi di emulatori di terminale.

+0

Grazie, ho già implementato le mie routine di paging. Darei un'occhiata per vedere cosa mi sono perso nei file che punti. Attualmente funziona nel mio sistema operativo, ma non ho provato nient'altro, quindi i miglioramenti portatili potrebbero essere utili. – Gra

1

Ho avuto la stessa domanda. C'è un cercapersone integrato nel pydoc module. L'ho incorporato così (che trovo logico e insoddisfacente ... sono comunque aperto a idee migliori).

Mi piace l'idea che sarebbe automatica se ci sono più di x risultati e il paging è attivo, che è possibile implementare, ma non fatto qui.

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")