Skip to content

CTk Rich Label

Lasha Kandelaki edited this page May 17, 2026 · 1 revision

CTkRichLabel

Read-only label that renders Unity-style inline rich-text tags — bold, italic, underline, color, background, size, and <noparse> blocks.

Wraps customtkinter.CTkRichLabel from CTkMaker's ctkmaker-core runtime (added in 5.5.0). There is no upstream CustomTkinter equivalent.

CTkRichLabel — parsed render

Properties

Groups appear in the panel in Content → Layout → Visual order.

Group Properties
Content text (multiline), rich_text (Parse Tags toggle), wrap (none / char / word)
Text font_family, font_size, Style (bold / italic / underline / strike), text_color
Geometry x, y, width, height
Rectangle corner_radius, optional Border (enabled / width / color), inner padding
Main Colors fg_color (transparent by default)

Exact set comes from the descriptor in app/widgets/ctk_rich_label.py.

Tag reference

Tag Form What it does
<b> </b> toggle Bold weight on top of the widget font.
<i> </i> toggle Italic slant on top of the widget font.
<u> </u> toggle Underline.
<color=v> </color> param Foreground colour. v = #rgb, #rrggbb, or named (red, green, blue, yellow, cyan, magenta, white, black, gray / grey, orange, purple, pink, brown).
<bg=v> </bg> param Background colour, same value formats as <color>.
<size=N> </size> param Absolute pixel size in CTk user units (matches CTkFont(size=N)).
<size=+N|-N> </size> param Size relative to the enclosing style (+N larger, -N smaller).
<noparse> </noparse> block Everything inside renders verbatim — no tag parsing.

Tags can be nested freely. Bold + italic + colour stack; nested <size> uses the inner value, not a multiplier.

Notable behaviour

  • Strict-lenient parser — unknown, malformed, or unclosed tags render as literal text. 3 < 5 and <color=banana>bad</color> both just appear as written. No exceptions, no auto-completion.
  • Partial-overlap recovery<b>aa<i>bb</b>cc</i> renders correctly: aa bold, bb bold+italic, cc italic. XML wouldn't allow it; CTkRichLabel does.
  • <noparse> is the escape hatch for valid-looking tags that should stay literal — no HTML entities needed (&lt; / &gt; are not parsed).
  • DPI-aware<size=N> values are in CTk user units; rendering multiplies through _get_widget_scaling() so text matches surrounding CTk widgets at any scaling factor.
  • Parse Tags toggle — turn off in the Content group to render the raw text verbatim (useful when you want to preview the markup itself, or when the source text comes from a user and may contain stray <).
  • Always read-only — caret hidden, scrollbars off, no Tab focus. For an editable rich-text surface use CTkTextbox with the rich_text property turned on.

Editing — Rich Text toolbar

The Rich Text row in the Properties panel opens an Edit Rich Text modal with a formatting toolbar above the multiline editor — no need to type tags by hand.

Button With selection With no selection
B / I / U Wraps selection in <b>…</b> / <i>…</i> / <u>…</u> Inserts an empty pair, caret inside
size Wraps in <size=13>…</size> — edit the 13 to any size you want Inserts <size=13></size>, caret inside
color ▼ Opens a colour dropdown (named colours as colour-painted rows + Custom hex…); wraps the selection in <color=value>…</color> Inserts an empty <color=value></color> pair, caret inside
bg ▼ Same as color but emits <bg=…>…</bg> Same

The caret parks at end-of-text when the dialog opens, so clicking a button before any interaction appends the tag pair to the end.

Double-click word selection stops at tag delimiters (<, >, =, ", /) — double-click on word inside <color=red>word</color> selects just word, leaving the surrounding tag intact for re-wrapping.

Available on both CTkRichLabel and CTkTextbox rows whose rich_text is on (added in v1.35.0).

Parse Tags on / off

The same text rendered with rich_text = True (parsed) on top, and rich_text = False (literal) below.

Parse Tags on

Parse Tags off

Exported code

self.title_label = ctk.CTkRichLabel(
    self,
    text="<b>Hello</b> <color=#50fa7b>world</color>",
    width=240, height=40,
    corner_radius=4, fg_color="transparent",
)
self.title_label.set_text("<b>Hello</b> <color=#50fa7b>world</color>")

If Parse Tags is off, the exporter emits self.title_label.set_rich_text_enabled(False) before set_text(...).


See alsoWidgets · CTkLabel · CTkTextbox

Clone this wiki locally