Search code examples
pythonpython-3.xtkinterttk

Create Derived Underline Text Style Using ttk Styling


Summary

How do I create a derived style with underlined text using ttk styling?

Details

I'm attempting to create a ttk style derived from the built-in TLabel style. The only difference between the built-in and the derived style should be that the text is underlined; it should inherit all other characteristics from the built-in TLabel style (i.e, if the TLabel font changes later, so should the Underline.TLabel).

I know that the basic way (not using ttk styling) is to create a new underlined font. However, as you can see from the sample code (below), the Underline.TLabel style displays in the correct (default) font, but the font-size is larger. I'm certain I'm missing something obvious, but haven't been able to find it through any Google searches, etc.

import tkinter as tk
from tkinter import font
from tkinter import ttk

def main():
    root = tk.Tk()
    style = ttk.Style(root)
    f = font.Font(underline=1)
    style.configure('Underline.TLabel', font=f)
    lbl0 = ttk.Label(root, text='Label 0', style='TLabel')
    lbl0.pack()
    lbl1 = ttk.Label(root, text='Label 1', style='Underline.TLabel')
    lbl1.pack()
    root.mainloop()


if __name__ == '__main__':
    main()

Solution

  • The problem is that you are assuming that font.Font(underline=1) returns the exact same font that is used by TLabel but with the underline bit turned on. This may or may not be true depending on the platform and how it's configured.

    If you need the custom font to be based off of the font used by TLabel, you should first make a copy of the font instead of relying on defaults.

    For example:

    original_font = font.nametofont(style.lookup("TLabel", "font"))
    f = font.Font(**original_font.configure())
    f.configure(underline=1)