2010-09-23 64 views
11

Quiero saber cómo cambiar el estilo de ciertas palabras y expresiones basadas en ciertos patrones.Cómo resaltar texto en un widget de texto tkinter

Estoy usando el widget Tkinter.Text y no estoy seguro de cómo hacer tal cosa (la misma idea de resaltar la sintaxis en los editores de texto). No estoy seguro, incluso si este es el widget adecuado para usar para este fin.

+0

Es el widget adecuado. Vea lo que hace ['idle'] (http://hg.python.org/cpython/file/63a00d019bb2/Lib/idlelib). – tzot

+0

@tzot Podría al menos dar una mejor indicación de qué archivos debería ver. 'idlelib' contiene muchos archivos y módulos, etc., y es un poco difícil encontrar algo, en mi opinión, sin una documentación real, y sobre todo si no tiene mucha experiencia. Dirigiré a los usuarios de este sitio web primero a este artículo: https://docs.python.org/3.5/library/idle.html – nbro

Respuesta

31

Es el widget adecuado para usar con estos fines. El concepto básico es asignar propiedades a etiquetas y aplicar etiquetas a rangos de texto en el widget. Puede utilizar el comando search del widget de texto para buscar cadenas que coincidan con su patrón, lo que le devolverá información suficiente para aplicar una etiqueta al rango coincidente.

Para ver un ejemplo de cómo aplicar etiquetas al texto, consulte mi respuesta a la pregunta Advanced Tkinter text box?. No es exactamente lo que quieres hacer, pero muestra el concepto básico.

A continuación se muestra un ejemplo de cómo puede ampliar la clase de texto para incluir un método para resaltar el texto que coincide con un patrón.

En este código, el patrón debe ser una cadena, no puede ser una expresión regular compilada. Además, el patrón debe cumplir con Tcl's syntax rules for regular expressions.

class CustomText(tk.Text): 
    '''A text widget with a new method, highlight_pattern() 

    example: 

    text = CustomText() 
    text.tag_configure("red", foreground="#ff0000") 
    text.highlight_pattern("this should be red", "red") 

    The highlight_pattern method is a simplified python 
    version of the tcl code at http://wiki.tcl.tk/3246 
    ''' 
    def __init__(self, *args, **kwargs): 
     tk.Text.__init__(self, *args, **kwargs) 

    def highlight_pattern(self, pattern, tag, start="1.0", end="end", 
          regexp=False): 
     '''Apply the given tag to all text that matches the given pattern 

     If 'regexp' is set to True, pattern will be treated as a regular 
     expression according to Tcl's regular expression syntax. 
     ''' 

     start = self.index(start) 
     end = self.index(end) 
     self.mark_set("matchStart", start) 
     self.mark_set("matchEnd", start) 
     self.mark_set("searchLimit", end) 

     count = tk.IntVar() 
     while True: 
      index = self.search(pattern, "matchEnd","searchLimit", 
           count=count, regexp=regexp) 
      if index == "": break 
      if count.get() == 0: break # degenerate pattern which matches zero-length strings 
      self.mark_set("matchStart", index) 
      self.mark_set("matchEnd", "%s+%sc" % (index, count.get())) 
      self.tag_add(tag, "matchStart", "matchEnd") 
+0

¡Gracias, esto me ha ayudado inmensamente! ¿Puedes decirme cómo cambiar esto para que acepte expresiones regulares como patrones? (Cuando intento, obtengo el objeto 'TypeError: '_sre.SRE_Pattern' no tiene el atributo '__getitem __'') – Lastalda

+0

@Lastalda: el método 'search' del widget de texto acepta un argumento de palabra clave llamado' regexp'. Si establece esto en 'True', el patrón se tratará como una expresión regular. He actualizado mi respuesta para incluir esta funcionalidad. Lamentablemente, la documentación específica de tkinter sobre el método 'search' es un poco escasa. Si lees la documentación oficial de tk se explica un poco mejor, aunque tienes que hacer una pequeña traducción mental de tcl a python. Ver http://tcl.tk/man/tcl8.5/TkCmd/text.htm#M120 –

+0

Gracias por mirarlo. Pero sigo teniendo el mismo error. :(¿Estoy haciendo algo mal con la expresión regular? Uso 'w.HighlightPattern (re.compile (" R \ d + ")," azul ")' y obtengo el error de seguimiento 'File" C: \ Python27 \ lib \ lib-tk \ Tkinter.py ", línea 3030, en búsqueda' 'si patrón y patrón [0] == '-': args.append ('-')' 'TypeError: '_sre.SRE_Pattern' objeto no tiene attribute '__getitem __' ' – Lastalda

Cuestiones relacionadas