web-dev-qa-db-fra.com

Comment changer la couleur de certains mots dans le widget texte tkinter?

J'ai un programme que je veux être comme le Python Shell et changer la couleur de certains mots quand ils sont tapés. Une aide?

18
Arctoran

L'idée principale est d'appliquer des balises aux parties de texte que vous souhaitez personnaliser. Vous pouvez créer vos balises en utilisant la méthode tag_configure , avec un style spécifique, puis il vous suffit d'appliquer cette balise à la partie du texte que vous souhaitez modifier à l'aide de la méthode tag_add . Vous pouvez également supprimer les balises à l'aide de la méthode tag_remove .

Voici un exemple qui utilise tag_configure, tag_add et tag_remove méthodes.

#!/usr/bin/env python3

import tkinter as tk
from tkinter.font import Font

class Pad(tk.Frame):

    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)

        self.toolbar = tk.Frame(self, bg="#eee")
        self.toolbar.pack(side="top", fill="x")

        self.bold_btn = tk.Button(self.toolbar, text="Bold", command=self.make_bold)
        self.bold_btn.pack(side="left")

        self.clear_btn = tk.Button(self.toolbar, text="Clear", command=self.clear)
        self.clear_btn.pack(side="left")

        # Creates a bold font
        self.bold_font = Font(family="Helvetica", size=14, weight="bold")

        self.text = tk.Text(self)
        self.text.insert("end", "Select part of text and then click 'Bold'...")
        self.text.focus()
        self.text.pack(fill="both", expand=True)

        # configuring a tag called BOLD
        self.text.tag_configure("BOLD", font=self.bold_font)

    def make_bold(self):
        # tk.TclError exception is raised if not text is selected
        try:
            self.text.tag_add("BOLD", "sel.first", "sel.last")        
        except tk.TclError:
            pass

    def clear(self):
        self.text.tag_remove("BOLD",  "1.0", 'end')


def demo():
    root = tk.Tk()
    Pad(root).pack(expand=1, fill="both")
    root.mainloop()


if __name__ == "__main__":
    demo()

Si vous ne savez pas quoi sel.first et sel.last sont, consultez ce message ou ce référence.

22
nbro

Jetez un œil à cet exemple:

from tkinter import *

root = Tk()

text = Text(root)
text.insert(INSERT, "Hello, world!\n")
text.insert(END, "This is a phrase.\n")
text.insert(END, "Bye bye...")
text.pack(expand=1, fill=BOTH)

# adding a tag to a part of text specifying the indices
text.tag_add("start", "1.8", "1.13")
text.tag_config("start", background="black", foreground="yellow")

root.mainloop()
9
Adem Öztaş

J'ai créé un client de chat. J'ai mis en évidence certaines parties de la conversation en utilisant un widget Text personnalisé assez facile à utiliser qui vous permet d'appliquer des balises à l'aide d'expressions régulières. Il était basé sur le post suivant: Comment mettre en surbrillance du texte dans un widget texte tkinter .

Voici un exemple d'utilisation:

# "text" is a Tkinter Text

# configuring a tag with a certain style (font color)
text.tag_configure("red", foreground="red")

# apply the tag "red" 
text.highlight_pattern("Word", "red")
9
Rnhmjoj

J'ai pu changer la couleur du texte pour chaque correspondance d'une expression régulière en utilisant le widget tkinter personnalisé Text pour obtenir un événement similaire à un 'text_changed':

import tkinter as tk

class CustomText(tk.Text):

def __init__(self, *args, **kwargs):
    """A text widget that report on internal widget commands"""
    tk.Text.__init__(self, *args, **kwargs)

    # create a proxy for the underlying widget
    self._orig = self._w + "_orig"
    self.tk.call("rename", self._w, self._orig)
    self.tk.createcommand(self._w, self._proxy)

def _proxy(self, command, *args):
    cmd = (self._orig, command) + args
    result = self.tk.call(cmd)
    if command in ("insert", "delete", "replace"):
        self.event_generate("<<TextModified>>")
    return result

Et puis, utilisez-le comme ça:

scr = CustomText(w)
scr.tag_configure('red', foreground = 'red')
scr.tag_configure('purple', foreground = '#a820a1')
scr.bind('<<TextModified>>', self.__textchanged__)

def __textchanged__(self, evt):
    for tag in evt.widget.tag_names():
        evt.widget.tag_remove(tag, '1.0', 'end')
    lines = evt.widget.get('1.0', 'end-1c').split('\n')
    for i, line in enumerate(lines):
        self.__applytag__(i, line, 'red', 'while|if', evt,widget) # your tags here
        self.__applytag__(i, line, 'purple', 'True', evt.widget)  # with a regex

@staticmethod
def __applytag__ (line, text, tag, regex, widget):
    indexes = [(m.start(), m.end()) for m in re.finditer(regex, text)]
    for x in indexes:
        widget.tag_add(tag, f'{line+1}.{x[0]}', f'{line+1}.{x[1]}')
0
Vinícius Gabriel