Is there a way in tkinter to italicize a single word in a text widget?

96 Views Asked by At

I am trying to make a text widget display some non-italicized characters in the same line as italicized ones. For example, I want it to say "This is my text widget" all in the same line.

As far as I know, you can only change the font formatting of the entire widget, not individual words. I've looked online quite a bit, but could not answer this question. I am wondering if this is possible, or if I should try a different method from using text widgets.

2

There are 2 best solutions below

2
Bryan Oakley On BEST ANSWER

You can apply a tag to a range of characters in a text widget. Each tag can be configured with a variety of styles and a custom font. Some styles can be applied directly to the tag, some need to be applied to a font that is associated with the tag. Italics is one such style that must be applied to a font.

import tkinter as tk
from tkinter.font import Font

root = tk.Tk()

normal_font = Font(family="helvetica", size=20)
italic_font = Font(family="helvetica", size=20, slant="italic")

text = tk.Text(root, wrap="none", width=40, height=10, font=normal_font)
text.pack(fill="both", expand=True)

text.tag_configure("italics", font=italic_font)

text.insert("end", "This is ", "", "my", "italics", " text widget")

root.mainloop()

Note: the insert method typically is used to insert one string at a time, but it actually takes a variable number of arguments in the form of text, tag, text, tag, ... (the final tag can be omitted).

In the above example, we insert the whole string using a single call to insert, but notice how we apply a null tag to some parts, and the tag "italics" to the word "my". That one call to insert does exactly the same thing as these three lines, but in a more concise format:

text.insert("end", "This is ")
text.insert("end", "my", "italics")
text.insert("end", " text widget")

Another way to do this is to insert the whole string at once, and then add the tag in a separate statement:

text.insert("end", "This is my text widget")
text.tag_add("italics", "1.8", "1.9")

screenshot

3
Ow Ji On

Unfortunately, tkinter's text widgets doesn't have direct access to font styles. A workaround could be to split the line of text into separate text widget entries, applying different styles to each entry. That could create something similar to the desired effect.

Example:

import tkinter as tk

root = tk.Tk()
root.geometry("400x100")

text_widget = tk.Text(root, wrap="none", height=1)
text_widget.pack()

text_widget.insert(tk.END, "This is ")
text_widget.tag_add("italic", "1.0", "1.4")
text_widget.tag_config("italic", font=("Times", 12, "italic"))

text_widget_italic = tk.Text(root, wrap="none", height=1)
text_widget_italic.pack()

text_widget_italic.insert(tk.END, "my")
text_widget_italic.tag_add("italic", "1.0", "1.2")
text_widget_italic.tag_config("italic", font=("Times", 12, "italic"))

text_widget.insert(tk.END, " text widget")
text_widget.tag_add("normal", "1.5", "1.end")
text_widget.tag_config("normal", font=("Times", 12))

root.mainloop()