6.3   Usando una clase

El caso anterior tiene una sola ventana de texto. Para tener varios archivos abiertos no tenemos que repetir el código para cada ventana. Lo que utilizamos es una clase y cada ventana es una instancia de la misma.

El código base para crear un editor que ya vimos será incluído en una clase editor, específicamente en la función __init__() que es su función contructora y se ejecuta cuando se crea una instancia.

Tk siempre crea una instancia de la clase Tk(), una ventana principal, que podría ser la ventana de inicio de la aplicación. En este caso la ocultamos desde el inicio con el método withdraw().

La clase editor tiene el método quit() para terminar la aplicación, y siguiente() y anterior() que son para activar otra de las ventanas de edición utilizando las teclas página siguiente y página anterior del teclado, cuyos eventos en Tkinter se llaman <Prior> y <Next>.

Usamos una lista editores inicialmente vacía, mediante un ciclo se va agregando una instancia de editor para cada parámetro que se proporcionó. El código es así:

class editor: 
    "Un area de texto simple." 
 
    def __init__( self, nombrearchivo ): 
        "Construye la instancia." 
        self.tl = Tkinter.Toplevel() 
        self.tl.title (nombrearchivo) 
        self.nombrearchivo = nombrearchivo 
        self.buffer = Tkinter.Text( self.tl, height=10) 
        self.buffer.pack() 
        self.buffer[ 'wrap'] = Tkinter.NONE 
        self.buffer[ 'background'] = 'white' 
        self.buffer[ 'foreground' ] = 'black' 
        self.buffer[ 'font'] = ( 'verdana', 14 ) 
        self.buffer.bind( '<Prior>', self.anterior ) 
        self.buffer.bind( '<Next>', self.siguiente) 
        self.buffer.bind( '<Control-q>', self.quit) 
 
        self.s = string.replace( open( self.nombrearchivo ).read(),'\015', '') 
        self.buffer.insert( Tkinter.END, self.s ) 
 
        if d.has_key( self.nombrearchivo ): 
            self.tl.geometry( d[ self.nombrearchivo ] ) 
        lineas = self.s.splitlines() 
        self.buffer['height'] = len( lineas ) + 1 
        self.buffer['width'] = max( map(len, lineas) ) + 1 
 
    def anterior( self, event ): 
        i = notas.index( self) - 1 
        if i < 0:  i = len(notas)-1 
        notas[i].buffer.focus_set() 
        notas[i].tl.lift() 
        return 'break' 
 
    def siguiente( self, event ): 
        i = ( notas.index( self) + 1 ) % len( notas ) 
        notas[i].buffer.focus_set() 
        notas[i].tl.lift() 
        return 'break' 
 
    def quit( self, event ): 
        "Actualiza posiciones, cierra ventanas, termina." 
        f = open( archivoconf, 'w' ) 
        for nota in notas: 
            d[ nota.nombrearchivo ] = nota.tl.geometry() 
            nota.tl.withdraw() 
        for llave, dato in sorted( d.items() ): 
            f.write( llave + ' ' + dato + '\n') 
            nota.tl.withdraw() 
        root.quit() 
 
def LeeConf(): 
    "Lee nombres y posiciones de archivoconf." 
    lineas = [] 
    try: 
        f = open( archivoconf ) 
        lineas = map( string.split, f.read().splitlines() ) 
    except: 
        print archivoconf, 'no existe' 
    for llave, dato in lineas: 
        d[llave] = dato 
 
 
import sys, string, Tkinter 
 
archivoconf = 'editor.conf' 
nombresarchivos = sys.argv[ 1:] 
if nombresarchivos: 
    d = {} 
    root = Tkinter.Tk() 
    root.withdraw() 
 
    LeeConf() 
    notas = [] 
    for nombrearchivo in nombresarchivos: 
        notas.append( editor( nombrearchivo ) ) 
    notas[0].buffer.focus_set() 
 
    root.mainloop()

servidor-http [0]7   Servidor HTTPservidor-http