How can I let the tkinter's text component show colorful words use '\033'?

Viewed 54

I have making a program.

It needs show some colorful words use this: \033[1mabc

I tryed this command and it failed:

import tkinter as tk
root=tk.Tk()
text=tk.Text(root)
text.insert('end', '\033[1mabc')

It shows a tofu and [1mabc. But I want get a red abc. How can I get it?

P.S. It will do like this:

import socket
import tkinter as tk
root=tk.Tk()

// connect the port use socket 'socket'

text=tk.Text(root)
text.insert('end', socket.read(1024))

And in the port of the computer:


//socket connected front is 'socket'

// when connect
import subprocess
command=subprocess.Popen(socket.read(1024), shell=True, output=subprocess.PIPE, error=subprocess.INPUT)
socket.send(command.output.read(1024))

// stop the 'command' Popen
3 Answers

You can't, not with tkinter.Text. \033[1m is an ANSI escape sequence, specifically the Select Graphics Rendition sequence, to change how a terminal should color the following text.

tkinter.Text does not interpret those sequences at all.

Here's an example of a function that supports a semblance of rich text in a tkinter.Text widget using tags:

import tkinter as tk


def set_text_with_attributes(text_widget, texts_and_attributes):
    i_start = text_widget.index(tk.INSERT)
    for i, (text, attributes) in enumerate(texts_and_attributes):
        text_widget.insert(tk.END, text)
        i_end = text_widget.index(tk.INSERT)
        tag_name = f'tag{i}'
        text_widget.tag_add(tag_name, i_start, i_end)
        text_widget.tag_config(tag_name, **attributes)
        i_start = i_end


root = tk.Tk()
text = tk.Text(root)

set_text_with_attributes(text, [
    ("Hello, ", {}),
    ("World!\n", {"foreground": "red"}),
    ("Once upon a time, ", {"foreground": "black"}),
    ("there was a ", {"foreground": "blue"}),
    ("fox", {"background": "orange"}),
    (" who jumped over ", {}),
    ("the ", {"foreground": "green"}),
    ("lazy ", {"background": "yellow"}),
    ("dog", {"foreground": "purple"}),
])

text.pack()

root.mainloop()

This shows

enter image description here

As for newbie. Just 15 lines try this.

import tkinter as tk

def onclick():
   pass

root = tk.Tk()
text = tk.Text(root)
text.insert(tk.INSERT, "It shows a tofu and [1mabc But I want get a red abc. How can I get it")
text.pack()

text.tag_add("here", "1.0", "1.4")
text.tag_add("start", "1.47", "1.51")
#text.tag_config("start", background="yellow", foreground="red")
text.tag_config("start", foreground="red")
root.mainloop()

If you want background and foreground. Comment in line13 and comment out line 14.

Output:

enter image description here

for intermediate levels. If you want, select any word or multiple words and highlight and then clear it. I added two buttons.

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="Highlight",
                      command=self.highlight_text)
        
        self.bold_btn.pack(side="left")

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

        self.text = tk.Text(self)
        self.text.insert("end", "It shows a tofu and [1mabc. But I want get a red abc. How can I get i")
        self.text.focus()
        self.text.pack(fill="both", expand=True)
        
        self.text.tag_configure("start", foreground="red")
        #self.text.tag_configure("start", background="black", foreground="red")

    def highlight_text(self):   
        try:
            self.text.tag_add("start", "sel.first", "sel.last")     
        except tk.TclError:
            pass


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


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


if __name__ == "__main__":
    demo()

Output:

enter image description here

Btw, if you want background and foreground. Comment out line 29 and comment in line 30.

Related