pythontkintertypography

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


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.


Solution

  • 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