Repository files navigation

Themed Tkinter Text

Repository:GitHub primary repositoryGitCode secondary repository

Language: 简体中文 | English | More translations are welcome!

Themed Tkinter Text widget with modern styling support.

Contributor CovenantMIT License

GitHub - TestPyPI - DownloadsPyPI - Version

Features

  • 🎨 Theme-aware text widget that automatically adapts to ttk themes
  • 📜 Built-in ScrolledText component with vertical/horizontal scrollbars
  • 🖥️ Native integration with ttk styles and themes
  • 🔄 Dynamic theme switching support

Screenshots

Windows 11Windows 10Windows 7

Example screenshots of Windows 11, Windows 10, and Windows 7.

Usage

Installation

You can install ttk-text using your preferred package manager.

Since ttk-text is currently unstable, I strongly recommend installing it in a virtual environment and pinning the exact version to avoid version conflicts.

# Using pip
pip install ttk-text
# Using uv
uv add ttk-text
# Using PDM
pdm add ttk-text
# Using Poetry
poetry add ttk-text

Using the Widgets

ttk-text provides three widgets:

  • ttk_text.ThemedTextFrame: A Frame for rendering the textbox style, which will bind to a Text widget.
  • ttk_text.ThemedText: A themed Text widget, as a replacement for tkinter.Text.
  • ttk_text.scrolled_text.ScrolledText: An extension of ThemedText with vertical/horizontal scrollbars, as a replacement for tkinter.scrolledtext.ScrolledText.

Using ThemedText and ScrolledText

You can use ThemedText and ScrolledText just like you would use tkinter.Text.

Here's an example:

fromtkinterimportTkfromttk_textimportThemedTextfromttk_text.scrolled_textimportScrolledTextroot=Tk()
themed_text=ThemedText(root)
themed_text.pack(fill="both", expand=True, padx="7p", pady="7p")
scrolled_text=ScrolledText(root)
scrolled_text.pack(fill="both", expand=True, padx="7p", pady=(0, "7p"))
root.mainloop()

Note

Currently, ttk style properties will override attributes you set such as selectbackground.

Adding Additional Components to ThemedText and ScrolledText

ThemedText itself doesn't handle theming; instead, it wraps itself in a ThemedTextFrame and lets the ThemedTextFrame handle theming. You can access this ThemedTextFrame via ThemedText#frame.

ThemedText positions itself at grid position (1, 1) within ThemedText#frame.

Layout of ThemedText#frame:

Index012
0
1ThemedText
2

ScrolledText also adds scrollbars and a frame for corner junction aesthetics.

Layout of ScrolledText#frame:

Index012
0
1ThemedTextScrollbar(orient="vertical")
2Scrollbar(orient="horizontal")Frame

You can place other components around (1, 1) like with ScrolledText, and call ThemedText#frame.bind_widget() to bind the component.

Using ThemedTextFrame

You can use ThemedTextFrame to theme third-party Text components.

After adding the component, you need to call ThemedText#frame.bind_text() to bind the third-party Text component.

For example, using tkinter.scrolledtext.ScrolledText:

importtkinter.scrolledtextfromtkinterimportTkfromttk_textimportThemedTextFrameroot=Tk()
text_frame=ThemedTextFrame(root)
text_frame.pack(fill="both", expand=True, padx="7p", pady="7p")
text_frame.grid_rowconfigure(1, weight=1)
text_frame.grid_columnconfigure(1, weight=1)
text=tkinter.scrolledtext.ScrolledText(text_frame)
text.grid(row=1, column=1, sticky="nsew")
text_frame.bind_text(text)
root.mainloop()

Note

ThemedTextFrame internally requires grid layout, you cannot use pack or place layouts.

Styling Configuration

You can use style name ThemedText.TEntry to configure styling.

PropertyDescription
borderwidthThemedTextFrame border width
paddingThemedTextFrame internal padding
fieldbackgroundText background color
foregroundText font color
textpaddingText external padding
insertwidthText cursor width
selectbackgroundText selection background color
selectforegroundText selection font color

For example, to set the border width to 1.5p:

fromtkinter.ttkimportStylestyle=Style()
style.configure("ThemedText.TEntry", borderwidth="1.5p")

Theme Compatibility

Some third-party themes may not be fully compatible with ttk-text. You can call the following function after setting the theme:

Sun Valley ttk theme
fromtkinterimportTkfromtkinter.ttkimportStyleimportsv_ttkdeffix_sv_ttk(style: Style):
ifsv_ttk.get_theme() =="light":
style.configure("ThemedText.TEntry", fieldbackground="#fdfdfd", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#f9f9f9"),
],
)
else:
style.configure("ThemedText.TEntry", fieldbackground="#292929", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#2f2f2f"),
("focus", "#1c1c1c"),
],
)
# Exampleapp=Tk()
sv_ttk.set_theme("light")
fix_sv_ttk(Style())
app.mainloop()
Azure-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_azure_ttk(style: Style):
ifstyle.theme_use() =="azure-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5)
else:
style.configure("ThemedText.TEntry", fieldbackground="#333333", textpadding=5)
# Exampleapp=Tk()
app.tk.call("source", "azure.tcl")
Style().theme_use("azure-light")
app.tk.call("set_theme", "light")
fix_azure_ttk(Style())
app.mainloop()
Forest-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_forest_ttk(style: Style):
ifstyle.theme_use() =="forest-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5, font="TkTextFont")
else:
style.configure("ThemedText.TEntry", fieldbackground="#313131", textpadding=5, font="TkTextFont")
# Exampleapp=Tk()
app.tk.call("source", "external-themes/forest-ttk-theme/forest-light.tcl")
Style().theme_use("forest-light")
fix_forest_ttk(Style())
app.mainloop()

Credits

This project is inspired by Git GUI's native-theming technique.

This is an independent Python implementation; no GPL-licensed code is included.

Contributing

See Contribution Guidelines for details.

License

This project is licensed under the MIT License, see the LICENSE file for details.

About

Themed Tkinter Text widget with modern styling support.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Themed Tkinter Text

Repository:GitHub primary repositoryGitCode secondary repository

Language: 简体中文 | English | More translations are welcome!

Themed Tkinter Text widget with modern styling support.

Contributor CovenantMIT License

GitHub - TestPyPI - DownloadsPyPI - Version

Features

  • 🎨 Theme-aware text widget that automatically adapts to ttk themes
  • 📜 Built-in ScrolledText component with vertical/horizontal scrollbars
  • 🖥️ Native integration with ttk styles and themes
  • 🔄 Dynamic theme switching support

Screenshots

Windows 11Windows 10Windows 7

Example screenshots of Windows 11, Windows 10, and Windows 7.

Usage

Installation

You can install ttk-text using your preferred package manager.

Since ttk-text is currently unstable, I strongly recommend installing it in a virtual environment and pinning the exact version to avoid version conflicts.

# Using pip
pip install ttk-text
# Using uv
uv add ttk-text
# Using PDM
pdm add ttk-text
# Using Poetry
poetry add ttk-text

Using the Widgets

ttk-text provides three widgets:

  • ttk_text.ThemedTextFrame: A Frame for rendering the textbox style, which will bind to a Text widget.
  • ttk_text.ThemedText: A themed Text widget, as a replacement for tkinter.Text.
  • ttk_text.scrolled_text.ScrolledText: An extension of ThemedText with vertical/horizontal scrollbars, as a replacement for tkinter.scrolledtext.ScrolledText.

Using ThemedText and ScrolledText

You can use ThemedText and ScrolledText just like you would use tkinter.Text.

Here's an example:

fromtkinterimportTkfromttk_textimportThemedTextfromttk_text.scrolled_textimportScrolledTextroot=Tk()
themed_text=ThemedText(root)
themed_text.pack(fill="both", expand=True, padx="7p", pady="7p")
scrolled_text=ScrolledText(root)
scrolled_text.pack(fill="both", expand=True, padx="7p", pady=(0, "7p"))
root.mainloop()

Note

Currently, ttk style properties will override attributes you set such as selectbackground.

Adding Additional Components to ThemedText and ScrolledText

ThemedText itself doesn't handle theming; instead, it wraps itself in a ThemedTextFrame and lets the ThemedTextFrame handle theming. You can access this ThemedTextFrame via ThemedText#frame.

ThemedText positions itself at grid position (1, 1) within ThemedText#frame.

Layout of ThemedText#frame:

Index012
0
1ThemedText
2

ScrolledText also adds scrollbars and a frame for corner junction aesthetics.

Layout of ScrolledText#frame:

Index012
0
1ThemedTextScrollbar(orient="vertical")
2Scrollbar(orient="horizontal")Frame

You can place other components around (1, 1) like with ScrolledText, and call ThemedText#frame.bind_widget() to bind the component.

Using ThemedTextFrame

You can use ThemedTextFrame to theme third-party Text components.

After adding the component, you need to call ThemedText#frame.bind_text() to bind the third-party Text component.

For example, using tkinter.scrolledtext.ScrolledText:

importtkinter.scrolledtextfromtkinterimportTkfromttk_textimportThemedTextFrameroot=Tk()
text_frame=ThemedTextFrame(root)
text_frame.pack(fill="both", expand=True, padx="7p", pady="7p")
text_frame.grid_rowconfigure(1, weight=1)
text_frame.grid_columnconfigure(1, weight=1)
text=tkinter.scrolledtext.ScrolledText(text_frame)
text.grid(row=1, column=1, sticky="nsew")
text_frame.bind_text(text)
root.mainloop()

Note

ThemedTextFrame internally requires grid layout, you cannot use pack or place layouts.

Styling Configuration

You can use style name ThemedText.TEntry to configure styling.

PropertyDescription
borderwidthThemedTextFrame border width
paddingThemedTextFrame internal padding
fieldbackgroundText background color
foregroundText font color
textpaddingText external padding
insertwidthText cursor width
selectbackgroundText selection background color
selectforegroundText selection font color

For example, to set the border width to 1.5p:

fromtkinter.ttkimportStylestyle=Style()
style.configure("ThemedText.TEntry", borderwidth="1.5p")

Theme Compatibility

Some third-party themes may not be fully compatible with ttk-text. You can call the following function after setting the theme:

Sun Valley ttk theme
fromtkinterimportTkfromtkinter.ttkimportStyleimportsv_ttkdeffix_sv_ttk(style: Style):
ifsv_ttk.get_theme() =="light":
style.configure("ThemedText.TEntry", fieldbackground="#fdfdfd", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#f9f9f9"),
],
)
else:
style.configure("ThemedText.TEntry", fieldbackground="#292929", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#2f2f2f"),
("focus", "#1c1c1c"),
],
)
# Exampleapp=Tk()
sv_ttk.set_theme("light")
fix_sv_ttk(Style())
app.mainloop()
Azure-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_azure_ttk(style: Style):
ifstyle.theme_use() =="azure-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5)
else:
style.configure("ThemedText.TEntry", fieldbackground="#333333", textpadding=5)
# Exampleapp=Tk()
app.tk.call("source", "azure.tcl")
Style().theme_use("azure-light")
app.tk.call("set_theme", "light")
fix_azure_ttk(Style())
app.mainloop()
Forest-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_forest_ttk(style: Style):
ifstyle.theme_use() =="forest-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5, font="TkTextFont")
else:
style.configure("ThemedText.TEntry", fieldbackground="#313131", textpadding=5, font="TkTextFont")
# Exampleapp=Tk()
app.tk.call("source", "external-themes/forest-ttk-theme/forest-light.tcl")
Style().theme_use("forest-light")
fix_forest_ttk(Style())
app.mainloop()

Credits

This project is inspired by Git GUI's native-theming technique.

This is an independent Python implementation; no GPL-licensed code is included.

Contributing

See Contribution Guidelines for details.

License

This project is licensed under the MIT License, see the LICENSE file for details.

About

Themed Tkinter Text widget with modern styling support.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Themed Tkinter Text

Repository:GitHub primary repositoryGitCode secondary repository

Language: 简体中文 | English | More translations are welcome!

Themed Tkinter Text widget with modern styling support.

Contributor CovenantMIT License

GitHub - TestPyPI - DownloadsPyPI - Version

Features

  • 🎨 Theme-aware text widget that automatically adapts to ttk themes
  • 📜 Built-in ScrolledText component with vertical/horizontal scrollbars
  • 🖥️ Native integration with ttk styles and themes
  • 🔄 Dynamic theme switching support

Screenshots

Windows 11Windows 10Windows 7

Example screenshots of Windows 11, Windows 10, and Windows 7.

Usage

Installation

You can install ttk-text using your preferred package manager.

Since ttk-text is currently unstable, I strongly recommend installing it in a virtual environment and pinning the exact version to avoid version conflicts.

# Using pip
pip install ttk-text
# Using uv
uv add ttk-text
# Using PDM
pdm add ttk-text
# Using Poetry
poetry add ttk-text

Using the Widgets

ttk-text provides three widgets:

  • ttk_text.ThemedTextFrame: A Frame for rendering the textbox style, which will bind to a Text widget.
  • ttk_text.ThemedText: A themed Text widget, as a replacement for tkinter.Text.
  • ttk_text.scrolled_text.ScrolledText: An extension of ThemedText with vertical/horizontal scrollbars, as a replacement for tkinter.scrolledtext.ScrolledText.

Using ThemedText and ScrolledText

You can use ThemedText and ScrolledText just like you would use tkinter.Text.

Here's an example:

fromtkinterimportTkfromttk_textimportThemedTextfromttk_text.scrolled_textimportScrolledTextroot=Tk()
themed_text=ThemedText(root)
themed_text.pack(fill="both", expand=True, padx="7p", pady="7p")
scrolled_text=ScrolledText(root)
scrolled_text.pack(fill="both", expand=True, padx="7p", pady=(0, "7p"))
root.mainloop()

Note

Currently, ttk style properties will override attributes you set such as selectbackground.

Adding Additional Components to ThemedText and ScrolledText

ThemedText itself doesn't handle theming; instead, it wraps itself in a ThemedTextFrame and lets the ThemedTextFrame handle theming. You can access this ThemedTextFrame via ThemedText#frame.

ThemedText positions itself at grid position (1, 1) within ThemedText#frame.

Layout of ThemedText#frame:

Index012
0
1ThemedText
2

ScrolledText also adds scrollbars and a frame for corner junction aesthetics.

Layout of ScrolledText#frame:

Index012
0
1ThemedTextScrollbar(orient="vertical")
2Scrollbar(orient="horizontal")Frame

You can place other components around (1, 1) like with ScrolledText, and call ThemedText#frame.bind_widget() to bind the component.

Using ThemedTextFrame

You can use ThemedTextFrame to theme third-party Text components.

After adding the component, you need to call ThemedText#frame.bind_text() to bind the third-party Text component.

For example, using tkinter.scrolledtext.ScrolledText:

importtkinter.scrolledtextfromtkinterimportTkfromttk_textimportThemedTextFrameroot=Tk()
text_frame=ThemedTextFrame(root)
text_frame.pack(fill="both", expand=True, padx="7p", pady="7p")
text_frame.grid_rowconfigure(1, weight=1)
text_frame.grid_columnconfigure(1, weight=1)
text=tkinter.scrolledtext.ScrolledText(text_frame)
text.grid(row=1, column=1, sticky="nsew")
text_frame.bind_text(text)
root.mainloop()

Note

ThemedTextFrame internally requires grid layout, you cannot use pack or place layouts.

Styling Configuration

You can use style name ThemedText.TEntry to configure styling.

PropertyDescription
borderwidthThemedTextFrame border width
paddingThemedTextFrame internal padding
fieldbackgroundText background color
foregroundText font color
textpaddingText external padding
insertwidthText cursor width
selectbackgroundText selection background color
selectforegroundText selection font color

For example, to set the border width to 1.5p:

fromtkinter.ttkimportStylestyle=Style()
style.configure("ThemedText.TEntry", borderwidth="1.5p")

Theme Compatibility

Some third-party themes may not be fully compatible with ttk-text. You can call the following function after setting the theme:

Sun Valley ttk theme
fromtkinterimportTkfromtkinter.ttkimportStyleimportsv_ttkdeffix_sv_ttk(style: Style):
ifsv_ttk.get_theme() =="light":
style.configure("ThemedText.TEntry", fieldbackground="#fdfdfd", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#f9f9f9"),
],
)
else:
style.configure("ThemedText.TEntry", fieldbackground="#292929", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#2f2f2f"),
("focus", "#1c1c1c"),
],
)
# Exampleapp=Tk()
sv_ttk.set_theme("light")
fix_sv_ttk(Style())
app.mainloop()
Azure-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_azure_ttk(style: Style):
ifstyle.theme_use() =="azure-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5)
else:
style.configure("ThemedText.TEntry", fieldbackground="#333333", textpadding=5)
# Exampleapp=Tk()
app.tk.call("source", "azure.tcl")
Style().theme_use("azure-light")
app.tk.call("set_theme", "light")
fix_azure_ttk(Style())
app.mainloop()
Forest-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_forest_ttk(style: Style):
ifstyle.theme_use() =="forest-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5, font="TkTextFont")
else:
style.configure("ThemedText.TEntry", fieldbackground="#313131", textpadding=5, font="TkTextFont")
# Exampleapp=Tk()
app.tk.call("source", "external-themes/forest-ttk-theme/forest-light.tcl")
Style().theme_use("forest-light")
fix_forest_ttk(Style())
app.mainloop()

Credits

This project is inspired by Git GUI's native-theming technique.

This is an independent Python implementation; no GPL-licensed code is included.

Contributing

See Contribution Guidelines for details.

License

This project is licensed under the MIT License, see the LICENSE file for details.

About

Themed Tkinter Text widget with modern styling support.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Themed Tkinter Text

Repository:GitHub primary repositoryGitCode secondary repository

Language: 简体中文 | English | More translations are welcome!

Themed Tkinter Text widget with modern styling support.

Contributor CovenantMIT License

GitHub - TestPyPI - DownloadsPyPI - Version

Features

  • 🎨 Theme-aware text widget that automatically adapts to ttk themes
  • 📜 Built-in ScrolledText component with vertical/horizontal scrollbars
  • 🖥️ Native integration with ttk styles and themes
  • 🔄 Dynamic theme switching support

Screenshots

Windows 11Windows 10Windows 7

Example screenshots of Windows 11, Windows 10, and Windows 7.

Usage

Installation

You can install ttk-text using your preferred package manager.

Since ttk-text is currently unstable, I strongly recommend installing it in a virtual environment and pinning the exact version to avoid version conflicts.

# Using pip
pip install ttk-text
# Using uv
uv add ttk-text
# Using PDM
pdm add ttk-text
# Using Poetry
poetry add ttk-text

Using the Widgets

ttk-text provides three widgets:

  • ttk_text.ThemedTextFrame: A Frame for rendering the textbox style, which will bind to a Text widget.
  • ttk_text.ThemedText: A themed Text widget, as a replacement for tkinter.Text.
  • ttk_text.scrolled_text.ScrolledText: An extension of ThemedText with vertical/horizontal scrollbars, as a replacement for tkinter.scrolledtext.ScrolledText.

Using ThemedText and ScrolledText

You can use ThemedText and ScrolledText just like you would use tkinter.Text.

Here's an example:

fromtkinterimportTkfromttk_textimportThemedTextfromttk_text.scrolled_textimportScrolledTextroot=Tk()
themed_text=ThemedText(root)
themed_text.pack(fill="both", expand=True, padx="7p", pady="7p")
scrolled_text=ScrolledText(root)
scrolled_text.pack(fill="both", expand=True, padx="7p", pady=(0, "7p"))
root.mainloop()

Note

Currently, ttk style properties will override attributes you set such as selectbackground.

Adding Additional Components to ThemedText and ScrolledText

ThemedText itself doesn't handle theming; instead, it wraps itself in a ThemedTextFrame and lets the ThemedTextFrame handle theming. You can access this ThemedTextFrame via ThemedText#frame.

ThemedText positions itself at grid position (1, 1) within ThemedText#frame.

Layout of ThemedText#frame:

Index012
0
1ThemedText
2

ScrolledText also adds scrollbars and a frame for corner junction aesthetics.

Layout of ScrolledText#frame:

Index012
0
1ThemedTextScrollbar(orient="vertical")
2Scrollbar(orient="horizontal")Frame

You can place other components around (1, 1) like with ScrolledText, and call ThemedText#frame.bind_widget() to bind the component.

Using ThemedTextFrame

You can use ThemedTextFrame to theme third-party Text components.

After adding the component, you need to call ThemedText#frame.bind_text() to bind the third-party Text component.

For example, using tkinter.scrolledtext.ScrolledText:

importtkinter.scrolledtextfromtkinterimportTkfromttk_textimportThemedTextFrameroot=Tk()
text_frame=ThemedTextFrame(root)
text_frame.pack(fill="both", expand=True, padx="7p", pady="7p")
text_frame.grid_rowconfigure(1, weight=1)
text_frame.grid_columnconfigure(1, weight=1)
text=tkinter.scrolledtext.ScrolledText(text_frame)
text.grid(row=1, column=1, sticky="nsew")
text_frame.bind_text(text)
root.mainloop()

Note

ThemedTextFrame internally requires grid layout, you cannot use pack or place layouts.

Styling Configuration

You can use style name ThemedText.TEntry to configure styling.

PropertyDescription
borderwidthThemedTextFrame border width
paddingThemedTextFrame internal padding
fieldbackgroundText background color
foregroundText font color
textpaddingText external padding
insertwidthText cursor width
selectbackgroundText selection background color
selectforegroundText selection font color

For example, to set the border width to 1.5p:

fromtkinter.ttkimportStylestyle=Style()
style.configure("ThemedText.TEntry", borderwidth="1.5p")

Theme Compatibility

Some third-party themes may not be fully compatible with ttk-text. You can call the following function after setting the theme:

Sun Valley ttk theme
fromtkinterimportTkfromtkinter.ttkimportStyleimportsv_ttkdeffix_sv_ttk(style: Style):
ifsv_ttk.get_theme() =="light":
style.configure("ThemedText.TEntry", fieldbackground="#fdfdfd", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#f9f9f9"),
],
)
else:
style.configure("ThemedText.TEntry", fieldbackground="#292929", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#2f2f2f"),
("focus", "#1c1c1c"),
],
)
# Exampleapp=Tk()
sv_ttk.set_theme("light")
fix_sv_ttk(Style())
app.mainloop()
Azure-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_azure_ttk(style: Style):
ifstyle.theme_use() =="azure-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5)
else:
style.configure("ThemedText.TEntry", fieldbackground="#333333", textpadding=5)
# Exampleapp=Tk()
app.tk.call("source", "azure.tcl")
Style().theme_use("azure-light")
app.tk.call("set_theme", "light")
fix_azure_ttk(Style())
app.mainloop()
Forest-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_forest_ttk(style: Style):
ifstyle.theme_use() =="forest-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5, font="TkTextFont")
else:
style.configure("ThemedText.TEntry", fieldbackground="#313131", textpadding=5, font="TkTextFont")
# Exampleapp=Tk()
app.tk.call("source", "external-themes/forest-ttk-theme/forest-light.tcl")
Style().theme_use("forest-light")
fix_forest_ttk(Style())
app.mainloop()

Credits

This project is inspired by Git GUI's native-theming technique.

This is an independent Python implementation; no GPL-licensed code is included.

Contributing

See Contribution Guidelines for details.

License

This project is licensed under the MIT License, see the LICENSE file for details.

About

Themed Tkinter Text widget with modern styling support.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Themed Tkinter Text

Repository:GitHub primary repositoryGitCode secondary repository

Language: 简体中文 | English | More translations are welcome!

Themed Tkinter Text widget with modern styling support.

Contributor CovenantMIT License

GitHub - TestPyPI - DownloadsPyPI - Version

Features

  • 🎨 Theme-aware text widget that automatically adapts to ttk themes
  • 📜 Built-in ScrolledText component with vertical/horizontal scrollbars
  • 🖥️ Native integration with ttk styles and themes
  • 🔄 Dynamic theme switching support

Screenshots

Windows 11Windows 10Windows 7

Example screenshots of Windows 11, Windows 10, and Windows 7.

Usage

Installation

You can install ttk-text using your preferred package manager.

Since ttk-text is currently unstable, I strongly recommend installing it in a virtual environment and pinning the exact version to avoid version conflicts.

# Using pip
pip install ttk-text
# Using uv
uv add ttk-text
# Using PDM
pdm add ttk-text
# Using Poetry
poetry add ttk-text

Using the Widgets

ttk-text provides three widgets:

  • ttk_text.ThemedTextFrame: A Frame for rendering the textbox style, which will bind to a Text widget.
  • ttk_text.ThemedText: A themed Text widget, as a replacement for tkinter.Text.
  • ttk_text.scrolled_text.ScrolledText: An extension of ThemedText with vertical/horizontal scrollbars, as a replacement for tkinter.scrolledtext.ScrolledText.

Using ThemedText and ScrolledText

You can use ThemedText and ScrolledText just like you would use tkinter.Text.

Here's an example:

fromtkinterimportTkfromttk_textimportThemedTextfromttk_text.scrolled_textimportScrolledTextroot=Tk()
themed_text=ThemedText(root)
themed_text.pack(fill="both", expand=True, padx="7p", pady="7p")
scrolled_text=ScrolledText(root)
scrolled_text.pack(fill="both", expand=True, padx="7p", pady=(0, "7p"))
root.mainloop()

Note

Currently, ttk style properties will override attributes you set such as selectbackground.

Adding Additional Components to ThemedText and ScrolledText

ThemedText itself doesn't handle theming; instead, it wraps itself in a ThemedTextFrame and lets the ThemedTextFrame handle theming. You can access this ThemedTextFrame via ThemedText#frame.

ThemedText positions itself at grid position (1, 1) within ThemedText#frame.

Layout of ThemedText#frame:

Index012
0
1ThemedText
2

ScrolledText also adds scrollbars and a frame for corner junction aesthetics.

Layout of ScrolledText#frame:

Index012
0
1ThemedTextScrollbar(orient="vertical")
2Scrollbar(orient="horizontal")Frame

You can place other components around (1, 1) like with ScrolledText, and call ThemedText#frame.bind_widget() to bind the component.

Using ThemedTextFrame

You can use ThemedTextFrame to theme third-party Text components.

After adding the component, you need to call ThemedText#frame.bind_text() to bind the third-party Text component.

For example, using tkinter.scrolledtext.ScrolledText:

importtkinter.scrolledtextfromtkinterimportTkfromttk_textimportThemedTextFrameroot=Tk()
text_frame=ThemedTextFrame(root)
text_frame.pack(fill="both", expand=True, padx="7p", pady="7p")
text_frame.grid_rowconfigure(1, weight=1)
text_frame.grid_columnconfigure(1, weight=1)
text=tkinter.scrolledtext.ScrolledText(text_frame)
text.grid(row=1, column=1, sticky="nsew")
text_frame.bind_text(text)
root.mainloop()

Note

ThemedTextFrame internally requires grid layout, you cannot use pack or place layouts.

Styling Configuration

You can use style name ThemedText.TEntry to configure styling.

PropertyDescription
borderwidthThemedTextFrame border width
paddingThemedTextFrame internal padding
fieldbackgroundText background color
foregroundText font color
textpaddingText external padding
insertwidthText cursor width
selectbackgroundText selection background color
selectforegroundText selection font color

For example, to set the border width to 1.5p:

fromtkinter.ttkimportStylestyle=Style()
style.configure("ThemedText.TEntry", borderwidth="1.5p")

Theme Compatibility

Some third-party themes may not be fully compatible with ttk-text. You can call the following function after setting the theme:

Sun Valley ttk theme
fromtkinterimportTkfromtkinter.ttkimportStyleimportsv_ttkdeffix_sv_ttk(style: Style):
ifsv_ttk.get_theme() =="light":
style.configure("ThemedText.TEntry", fieldbackground="#fdfdfd", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#f9f9f9"),
],
)
else:
style.configure("ThemedText.TEntry", fieldbackground="#292929", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#2f2f2f"),
("focus", "#1c1c1c"),
],
)
# Exampleapp=Tk()
sv_ttk.set_theme("light")
fix_sv_ttk(Style())
app.mainloop()
Azure-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_azure_ttk(style: Style):
ifstyle.theme_use() =="azure-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5)
else:
style.configure("ThemedText.TEntry", fieldbackground="#333333", textpadding=5)
# Exampleapp=Tk()
app.tk.call("source", "azure.tcl")
Style().theme_use("azure-light")
app.tk.call("set_theme", "light")
fix_azure_ttk(Style())
app.mainloop()
Forest-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_forest_ttk(style: Style):
ifstyle.theme_use() =="forest-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5, font="TkTextFont")
else:
style.configure("ThemedText.TEntry", fieldbackground="#313131", textpadding=5, font="TkTextFont")
# Exampleapp=Tk()
app.tk.call("source", "external-themes/forest-ttk-theme/forest-light.tcl")
Style().theme_use("forest-light")
fix_forest_ttk(Style())
app.mainloop()

Credits

This project is inspired by Git GUI's native-theming technique.

This is an independent Python implementation; no GPL-licensed code is included.

Contributing

See Contribution Guidelines for details.

License

This project is licensed under the MIT License, see the LICENSE file for details.

About

Themed Tkinter Text widget with modern styling support.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Themed Tkinter Text

Repository:GitHub primary repositoryGitCode secondary repository

Language: 简体中文 | English | More translations are welcome!

Themed Tkinter Text widget with modern styling support.

Contributor CovenantMIT License

GitHub - TestPyPI - DownloadsPyPI - Version

Features

  • 🎨 Theme-aware text widget that automatically adapts to ttk themes
  • 📜 Built-in ScrolledText component with vertical/horizontal scrollbars
  • 🖥️ Native integration with ttk styles and themes
  • 🔄 Dynamic theme switching support

Screenshots

Windows 11Windows 10Windows 7

Example screenshots of Windows 11, Windows 10, and Windows 7.

Usage

Installation

You can install ttk-text using your preferred package manager.

Since ttk-text is currently unstable, I strongly recommend installing it in a virtual environment and pinning the exact version to avoid version conflicts.

# Using pip
pip install ttk-text
# Using uv
uv add ttk-text
# Using PDM
pdm add ttk-text
# Using Poetry
poetry add ttk-text

Using the Widgets

ttk-text provides three widgets:

  • ttk_text.ThemedTextFrame: A Frame for rendering the textbox style, which will bind to a Text widget.
  • ttk_text.ThemedText: A themed Text widget, as a replacement for tkinter.Text.
  • ttk_text.scrolled_text.ScrolledText: An extension of ThemedText with vertical/horizontal scrollbars, as a replacement for tkinter.scrolledtext.ScrolledText.

Using ThemedText and ScrolledText

You can use ThemedText and ScrolledText just like you would use tkinter.Text.

Here's an example:

fromtkinterimportTkfromttk_textimportThemedTextfromttk_text.scrolled_textimportScrolledTextroot=Tk()
themed_text=ThemedText(root)
themed_text.pack(fill="both", expand=True, padx="7p", pady="7p")
scrolled_text=ScrolledText(root)
scrolled_text.pack(fill="both", expand=True, padx="7p", pady=(0, "7p"))
root.mainloop()

Note

Currently, ttk style properties will override attributes you set such as selectbackground.

Adding Additional Components to ThemedText and ScrolledText

ThemedText itself doesn't handle theming; instead, it wraps itself in a ThemedTextFrame and lets the ThemedTextFrame handle theming. You can access this ThemedTextFrame via ThemedText#frame.

ThemedText positions itself at grid position (1, 1) within ThemedText#frame.

Layout of ThemedText#frame:

Index012
0
1ThemedText
2

ScrolledText also adds scrollbars and a frame for corner junction aesthetics.

Layout of ScrolledText#frame:

Index012
0
1ThemedTextScrollbar(orient="vertical")
2Scrollbar(orient="horizontal")Frame

You can place other components around (1, 1) like with ScrolledText, and call ThemedText#frame.bind_widget() to bind the component.

Using ThemedTextFrame

You can use ThemedTextFrame to theme third-party Text components.

After adding the component, you need to call ThemedText#frame.bind_text() to bind the third-party Text component.

For example, using tkinter.scrolledtext.ScrolledText:

importtkinter.scrolledtextfromtkinterimportTkfromttk_textimportThemedTextFrameroot=Tk()
text_frame=ThemedTextFrame(root)
text_frame.pack(fill="both", expand=True, padx="7p", pady="7p")
text_frame.grid_rowconfigure(1, weight=1)
text_frame.grid_columnconfigure(1, weight=1)
text=tkinter.scrolledtext.ScrolledText(text_frame)
text.grid(row=1, column=1, sticky="nsew")
text_frame.bind_text(text)
root.mainloop()

Note

ThemedTextFrame internally requires grid layout, you cannot use pack or place layouts.

Styling Configuration

You can use style name ThemedText.TEntry to configure styling.

PropertyDescription
borderwidthThemedTextFrame border width
paddingThemedTextFrame internal padding
fieldbackgroundText background color
foregroundText font color
textpaddingText external padding
insertwidthText cursor width
selectbackgroundText selection background color
selectforegroundText selection font color

For example, to set the border width to 1.5p:

fromtkinter.ttkimportStylestyle=Style()
style.configure("ThemedText.TEntry", borderwidth="1.5p")

Theme Compatibility

Some third-party themes may not be fully compatible with ttk-text. You can call the following function after setting the theme:

Sun Valley ttk theme
fromtkinterimportTkfromtkinter.ttkimportStyleimportsv_ttkdeffix_sv_ttk(style: Style):
ifsv_ttk.get_theme() =="light":
style.configure("ThemedText.TEntry", fieldbackground="#fdfdfd", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#f9f9f9"),
],
)
else:
style.configure("ThemedText.TEntry", fieldbackground="#292929", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#2f2f2f"),
("focus", "#1c1c1c"),
],
)
# Exampleapp=Tk()
sv_ttk.set_theme("light")
fix_sv_ttk(Style())
app.mainloop()
Azure-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_azure_ttk(style: Style):
ifstyle.theme_use() =="azure-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5)
else:
style.configure("ThemedText.TEntry", fieldbackground="#333333", textpadding=5)
# Exampleapp=Tk()
app.tk.call("source", "azure.tcl")
Style().theme_use("azure-light")
app.tk.call("set_theme", "light")
fix_azure_ttk(Style())
app.mainloop()
Forest-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_forest_ttk(style: Style):
ifstyle.theme_use() =="forest-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5, font="TkTextFont")
else:
style.configure("ThemedText.TEntry", fieldbackground="#313131", textpadding=5, font="TkTextFont")
# Exampleapp=Tk()
app.tk.call("source", "external-themes/forest-ttk-theme/forest-light.tcl")
Style().theme_use("forest-light")
fix_forest_ttk(Style())
app.mainloop()

Credits

This project is inspired by Git GUI's native-theming technique.

This is an independent Python implementation; no GPL-licensed code is included.

Contributing

See Contribution Guidelines for details.

License

This project is licensed under the MIT License, see the LICENSE file for details.

About

Themed Tkinter Text widget with modern styling support.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Themed Tkinter Text

Repository:GitHub primary repositoryGitCode secondary repository

Language: 简体中文 | English | More translations are welcome!

Themed Tkinter Text widget with modern styling support.

Contributor CovenantMIT License

GitHub - TestPyPI - DownloadsPyPI - Version

Features

  • 🎨 Theme-aware text widget that automatically adapts to ttk themes
  • 📜 Built-in ScrolledText component with vertical/horizontal scrollbars
  • 🖥️ Native integration with ttk styles and themes
  • 🔄 Dynamic theme switching support

Screenshots

Windows 11Windows 10Windows 7

Example screenshots of Windows 11, Windows 10, and Windows 7.

Usage

Installation

You can install ttk-text using your preferred package manager.

Since ttk-text is currently unstable, I strongly recommend installing it in a virtual environment and pinning the exact version to avoid version conflicts.

# Using pip
pip install ttk-text
# Using uv
uv add ttk-text
# Using PDM
pdm add ttk-text
# Using Poetry
poetry add ttk-text

Using the Widgets

ttk-text provides three widgets:

  • ttk_text.ThemedTextFrame: A Frame for rendering the textbox style, which will bind to a Text widget.
  • ttk_text.ThemedText: A themed Text widget, as a replacement for tkinter.Text.
  • ttk_text.scrolled_text.ScrolledText: An extension of ThemedText with vertical/horizontal scrollbars, as a replacement for tkinter.scrolledtext.ScrolledText.

Using ThemedText and ScrolledText

You can use ThemedText and ScrolledText just like you would use tkinter.Text.

Here's an example:

fromtkinterimportTkfromttk_textimportThemedTextfromttk_text.scrolled_textimportScrolledTextroot=Tk()
themed_text=ThemedText(root)
themed_text.pack(fill="both", expand=True, padx="7p", pady="7p")
scrolled_text=ScrolledText(root)
scrolled_text.pack(fill="both", expand=True, padx="7p", pady=(0, "7p"))
root.mainloop()

Note

Currently, ttk style properties will override attributes you set such as selectbackground.

Adding Additional Components to ThemedText and ScrolledText

ThemedText itself doesn't handle theming; instead, it wraps itself in a ThemedTextFrame and lets the ThemedTextFrame handle theming. You can access this ThemedTextFrame via ThemedText#frame.

ThemedText positions itself at grid position (1, 1) within ThemedText#frame.

Layout of ThemedText#frame:

Index012
0
1ThemedText
2

ScrolledText also adds scrollbars and a frame for corner junction aesthetics.

Layout of ScrolledText#frame:

Index012
0
1ThemedTextScrollbar(orient="vertical")
2Scrollbar(orient="horizontal")Frame

You can place other components around (1, 1) like with ScrolledText, and call ThemedText#frame.bind_widget() to bind the component.

Using ThemedTextFrame

You can use ThemedTextFrame to theme third-party Text components.

After adding the component, you need to call ThemedText#frame.bind_text() to bind the third-party Text component.

For example, using tkinter.scrolledtext.ScrolledText:

importtkinter.scrolledtextfromtkinterimportTkfromttk_textimportThemedTextFrameroot=Tk()
text_frame=ThemedTextFrame(root)
text_frame.pack(fill="both", expand=True, padx="7p", pady="7p")
text_frame.grid_rowconfigure(1, weight=1)
text_frame.grid_columnconfigure(1, weight=1)
text=tkinter.scrolledtext.ScrolledText(text_frame)
text.grid(row=1, column=1, sticky="nsew")
text_frame.bind_text(text)
root.mainloop()

Note

ThemedTextFrame internally requires grid layout, you cannot use pack or place layouts.

Styling Configuration

You can use style name ThemedText.TEntry to configure styling.

PropertyDescription
borderwidthThemedTextFrame border width
paddingThemedTextFrame internal padding
fieldbackgroundText background color
foregroundText font color
textpaddingText external padding
insertwidthText cursor width
selectbackgroundText selection background color
selectforegroundText selection font color

For example, to set the border width to 1.5p:

fromtkinter.ttkimportStylestyle=Style()
style.configure("ThemedText.TEntry", borderwidth="1.5p")

Theme Compatibility

Some third-party themes may not be fully compatible with ttk-text. You can call the following function after setting the theme:

Sun Valley ttk theme
fromtkinterimportTkfromtkinter.ttkimportStyleimportsv_ttkdeffix_sv_ttk(style: Style):
ifsv_ttk.get_theme() =="light":
style.configure("ThemedText.TEntry", fieldbackground="#fdfdfd", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#f9f9f9"),
],
)
else:
style.configure("ThemedText.TEntry", fieldbackground="#292929", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#2f2f2f"),
("focus", "#1c1c1c"),
],
)
# Exampleapp=Tk()
sv_ttk.set_theme("light")
fix_sv_ttk(Style())
app.mainloop()
Azure-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_azure_ttk(style: Style):
ifstyle.theme_use() =="azure-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5)
else:
style.configure("ThemedText.TEntry", fieldbackground="#333333", textpadding=5)
# Exampleapp=Tk()
app.tk.call("source", "azure.tcl")
Style().theme_use("azure-light")
app.tk.call("set_theme", "light")
fix_azure_ttk(Style())
app.mainloop()
Forest-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_forest_ttk(style: Style):
ifstyle.theme_use() =="forest-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5, font="TkTextFont")
else:
style.configure("ThemedText.TEntry", fieldbackground="#313131", textpadding=5, font="TkTextFont")
# Exampleapp=Tk()
app.tk.call("source", "external-themes/forest-ttk-theme/forest-light.tcl")
Style().theme_use("forest-light")
fix_forest_ttk(Style())
app.mainloop()

Credits

This project is inspired by Git GUI's native-theming technique.

This is an independent Python implementation; no GPL-licensed code is included.

Contributing

See Contribution Guidelines for details.

License

This project is licensed under the MIT License, see the LICENSE file for details.

About

Themed Tkinter Text widget with modern styling support.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Themed Tkinter Text

Repository:GitHub primary repositoryGitCode secondary repository

Language: 简体中文 | English | More translations are welcome!

Themed Tkinter Text widget with modern styling support.

Contributor CovenantMIT License

GitHub - TestPyPI - DownloadsPyPI - Version

Features

  • 🎨 Theme-aware text widget that automatically adapts to ttk themes
  • 📜 Built-in ScrolledText component with vertical/horizontal scrollbars
  • 🖥️ Native integration with ttk styles and themes
  • 🔄 Dynamic theme switching support

Screenshots

Windows 11Windows 10Windows 7

Example screenshots of Windows 11, Windows 10, and Windows 7.

Usage

Installation

You can install ttk-text using your preferred package manager.

Since ttk-text is currently unstable, I strongly recommend installing it in a virtual environment and pinning the exact version to avoid version conflicts.

# Using pip
pip install ttk-text
# Using uv
uv add ttk-text
# Using PDM
pdm add ttk-text
# Using Poetry
poetry add ttk-text

Using the Widgets

ttk-text provides three widgets:

  • ttk_text.ThemedTextFrame: A Frame for rendering the textbox style, which will bind to a Text widget.
  • ttk_text.ThemedText: A themed Text widget, as a replacement for tkinter.Text.
  • ttk_text.scrolled_text.ScrolledText: An extension of ThemedText with vertical/horizontal scrollbars, as a replacement for tkinter.scrolledtext.ScrolledText.

Using ThemedText and ScrolledText

You can use ThemedText and ScrolledText just like you would use tkinter.Text.

Here's an example:

fromtkinterimportTkfromttk_textimportThemedTextfromttk_text.scrolled_textimportScrolledTextroot=Tk()
themed_text=ThemedText(root)
themed_text.pack(fill="both", expand=True, padx="7p", pady="7p")
scrolled_text=ScrolledText(root)
scrolled_text.pack(fill="both", expand=True, padx="7p", pady=(0, "7p"))
root.mainloop()

Note

Currently, ttk style properties will override attributes you set such as selectbackground.

Adding Additional Components to ThemedText and ScrolledText

ThemedText itself doesn't handle theming; instead, it wraps itself in a ThemedTextFrame and lets the ThemedTextFrame handle theming. You can access this ThemedTextFrame via ThemedText#frame.

ThemedText positions itself at grid position (1, 1) within ThemedText#frame.

Layout of ThemedText#frame:

Index012
0
1ThemedText
2

ScrolledText also adds scrollbars and a frame for corner junction aesthetics.

Layout of ScrolledText#frame:

Index012
0
1ThemedTextScrollbar(orient="vertical")
2Scrollbar(orient="horizontal")Frame

You can place other components around (1, 1) like with ScrolledText, and call ThemedText#frame.bind_widget() to bind the component.

Using ThemedTextFrame

You can use ThemedTextFrame to theme third-party Text components.

After adding the component, you need to call ThemedText#frame.bind_text() to bind the third-party Text component.

For example, using tkinter.scrolledtext.ScrolledText:

importtkinter.scrolledtextfromtkinterimportTkfromttk_textimportThemedTextFrameroot=Tk()
text_frame=ThemedTextFrame(root)
text_frame.pack(fill="both", expand=True, padx="7p", pady="7p")
text_frame.grid_rowconfigure(1, weight=1)
text_frame.grid_columnconfigure(1, weight=1)
text=tkinter.scrolledtext.ScrolledText(text_frame)
text.grid(row=1, column=1, sticky="nsew")
text_frame.bind_text(text)
root.mainloop()

Note

ThemedTextFrame internally requires grid layout, you cannot use pack or place layouts.

Styling Configuration

You can use style name ThemedText.TEntry to configure styling.

PropertyDescription
borderwidthThemedTextFrame border width
paddingThemedTextFrame internal padding
fieldbackgroundText background color
foregroundText font color
textpaddingText external padding
insertwidthText cursor width
selectbackgroundText selection background color
selectforegroundText selection font color

For example, to set the border width to 1.5p:

fromtkinter.ttkimportStylestyle=Style()
style.configure("ThemedText.TEntry", borderwidth="1.5p")

Theme Compatibility

Some third-party themes may not be fully compatible with ttk-text. You can call the following function after setting the theme:

Sun Valley ttk theme
fromtkinterimportTkfromtkinter.ttkimportStyleimportsv_ttkdeffix_sv_ttk(style: Style):
ifsv_ttk.get_theme() =="light":
style.configure("ThemedText.TEntry", fieldbackground="#fdfdfd", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#f9f9f9"),
],
)
else:
style.configure("ThemedText.TEntry", fieldbackground="#292929", textpadding=5)
style.map(
"ThemedText.TEntry",
fieldbackground=[
("hover", "!focus", "#2f2f2f"),
("focus", "#1c1c1c"),
],
)
# Exampleapp=Tk()
sv_ttk.set_theme("light")
fix_sv_ttk(Style())
app.mainloop()
Azure-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_azure_ttk(style: Style):
ifstyle.theme_use() =="azure-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5)
else:
style.configure("ThemedText.TEntry", fieldbackground="#333333", textpadding=5)
# Exampleapp=Tk()
app.tk.call("source", "azure.tcl")
Style().theme_use("azure-light")
app.tk.call("set_theme", "light")
fix_azure_ttk(Style())
app.mainloop()
Forest-ttk-theme
fromtkinterimportTkfromtkinter.ttkimportStyledeffix_forest_ttk(style: Style):
ifstyle.theme_use() =="forest-light":
style.configure("ThemedText.TEntry", fieldbackground="#ffffff", textpadding=5, font="TkTextFont")
else:
style.configure("ThemedText.TEntry", fieldbackground="#313131", textpadding=5, font="TkTextFont")
# Exampleapp=Tk()
app.tk.call("source", "external-themes/forest-ttk-theme/forest-light.tcl")
Style().theme_use("forest-light")
fix_forest_ttk(Style())
app.mainloop()

Credits

This project is inspired by Git GUI's native-theming technique.

This is an independent Python implementation; no GPL-licensed code is included.

Contributing

See Contribution Guidelines for details.

License

This project is licensed under the MIT License, see the LICENSE file for details.

About

Themed Tkinter Text widget with modern styling support.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages