How can I make part of the text in the Entry bold and change its background color?

Viewed 1096

I am creating a Tkinter-based GUI, and it has an Entry widget. I want to make a part of its text bold and change its background color. But I can't figure out how can I do that. If I use the Text widget I can just use tags but it looks like they can't be used with Entry widget:

This code is using the Text widget:

import tkinter as tk
from tkinter.font import Font


root = tk.Tk()
text = tk.Text(root, font=Font(size=12))
text.insert("1.0", "I want THIS PART to be bold and have red background")
text.tag_configure("bold-and-red", font=Font(size=12, weight="bold"), background="red")
text.tag_add("bold-and-red", "1.7", "1.16")
text.pack()
root.mainloop()

Everything works fine (the Text widget is shown and "THIS PART" is bold and has a red background)

And this code is using the Entry widget:

import tkinter as tk
from tkinter.font import Font


root = tk.Tk()
entry = tk.Entry(root, font=Font(size=12))
entry.insert(0, "I want THIS PART to be bold and have red background")
entry.tag_configure("bold-and-red", font=Font(size=12, weight="bold"), background="red")
entry.tag_add("bold-and-red", 7, 16)
entry.pack()
root.mainloop()

I just get the error:

AttributeError: 'Entry' object has no attribute 'tag_configure'

Is there a way to do what I want for Entry widget?

2 Answers

As @BryanOakley said, the only way to change the appearance of only certain characters is to use a custom Text widget.

Here is an example implementation:

import tkinter as tk
from tkinter.font import Font


class OneLineText(tk.Text):
    def __init__(self, master, *args, **kwargs):     
        super().__init__(master, *args, height=1, wrap="none", **kwargs)

        self.bind("<Return>", lambda event: "break")
        self.bind("<Key>", self.on_keypress)
        self.bind("<Control-a>", self.select_all)
        self.bind("<Control-A>", self.select_all)
        self.bind("<Control-v>", lambda event: self.see("end"))
        self.bind("<Control-V>", lambda event: self.see("end"))

    def on_keypress(self, event):
        self.see("end-1c")

    def select_all(self, event):
        self.tag_add("sel", "1.0", "end-1c")
        return "break"

    def insert(self, index, string):
        string = string.replace("\n", "")
        if isinstance(index, int):
            super().insert("1.{}".format(index), string)
            return
        if index == "end":
            super().insert("end-1c", string)
            return
        super().insert(index, string)

    def get(self):
        return super().get("1.0", "end-1c")

root = tk.Tk()
entry = OneLineText(root, font=Font(size=12))
entry.insert(0, "I want THIS PART to be bold and have red background")
entry.tag_configure("bold-and-red", font=Font(size=12, weight="bold"), background="red")
entry.tag_add("bold-and-red", "1.7", "1.16")
entry.pack()
root.mainloop()

insert and get methods of the Text widget are modified to work like they do in the Entry widget.

A screenshot

How can I make part of the text in the Entry bold and change its background color? ... If I use the Text widget I can just use tags but it looks like they can't be used with Entry widget:

You are correct: you can't change the appearance of only some of the characters in an entry widget, other than through the selection mechanism.

If you want to change the appearance of only certain characters, you will need to use a one-line Text widget instead.

Related