Python Terminal Toolkit for creating sophisticated text-based user interfaces with Qt-like API and full widget support
—
Advanced color support, drawing capabilities, and theming system with ANSI color support, gradients, and custom drawing operations.
TTkColor provides comprehensive color support for terminal applications with ANSI escape sequences.
class TTkColor:
def __init__(self, fg=None, bg=None, **kwargs):
"""
Initialize a color object.
Parameters:
- fg: Foreground color (hex string, RGB tuple, or color name)
- bg: Background color (hex string, RGB tuple, or color name)
- bold (bool): Bold text style
- italic (bool): Italic text style
- underline (bool): Underline text style
"""
def foreground(self):
"""Get the foreground color."""
def setForeground(self, color):
"""Set the foreground color."""
def background(self):
"""Get the background color."""
def setBackground(self, color):
"""Set the background color."""
def isBold(self):
"""Check if bold style is enabled."""
def setBold(self, bold):
"""Enable/disable bold style."""
def isItalic(self):
"""Check if italic style is enabled."""
def setItalic(self, italic):
"""Enable/disable italic style."""
def isUnderline(self):
"""Check if underline style is enabled."""
def setUnderline(self, underline):
"""Enable/disable underline style."""
def isStrikeOut(self):
"""Check if strikeout style is enabled."""
def setStrikeOut(self, strikeOut):
"""Enable/disable strikeout style."""
def copy(self):
"""Create a copy of this color."""
def lighter(self, factor=150):
"""Return a lighter version of this color."""
def darker(self, factor=150):
"""Return a darker version of this color."""
def toAnsi(self):
"""Convert to ANSI escape sequence."""
# Class methods for predefined colors
@classmethod
def RST(cls):
"""Reset color."""
@classmethod
def BLACK(cls):
"""Black color."""
@classmethod
def RED(cls):
"""Red color."""
@classmethod
def GREEN(cls):
"""Green color."""
@classmethod
def YELLOW(cls):
"""Yellow color."""
@classmethod
def BLUE(cls):
"""Blue color."""
@classmethod
def MAGENTA(cls):
"""Magenta color."""
@classmethod
def CYAN(cls):
"""Cyan color."""
@classmethod
def WHITE(cls):
"""White color."""TTkColorModifier provides color manipulation utilities.
class TTkColorModifier:
def __init__(self, color):
"""Initialize with base color."""
def lighten(self, amount):
"""Lighten the color by amount."""
def darken(self, amount):
"""Darken the color by amount."""
def saturate(self, amount):
"""Increase saturation."""
def desaturate(self, amount):
"""Decrease saturation."""
def adjust_hue(self, degrees):
"""Adjust hue by degrees."""
def complement(self):
"""Get complementary color."""
def analogous(self, count=3):
"""Get analogous colors."""
def triadic(self):
"""Get triadic color scheme."""TTkColorGradient and TTkLinearGradient provide gradient color support.
class TTkColorGradient:
def __init__(self):
"""Initialize a color gradient."""
def addColorStop(self, position, color):
"""
Add a color stop to the gradient.
Parameters:
- position (float): Position from 0.0 to 1.0
- color (TTkColor): Color at this position
"""
def colorAt(self, position):
"""Get interpolated color at position."""
def colorStops(self):
"""Get list of color stops."""
def setColorStops(self, stops):
"""Set color stops from list."""
class TTkLinearGradient(TTkColorGradient):
def __init__(self, start, stop):
"""
Initialize a linear gradient.
Parameters:
- start (TTkPoint): Start point
- stop (TTkPoint): End point
"""
def setStart(self, point):
"""Set gradient start point."""
def start(self):
"""Get gradient start point."""
def setStop(self, point):
"""Set gradient end point."""
def stop(self):
"""Get gradient end point."""TTkString extends string functionality with color and formatting support.
class TTkString:
def __init__(self, text="", color=None):
"""
Initialize a colored string.
Parameters:
- text (str): Text content
- color (TTkColor): Text color
"""
def __str__(self):
"""Convert to string representation."""
def __len__(self):
"""Get string length (excluding color codes)."""
def __add__(self, other):
"""Concatenate with another string or TTkString."""
def setText(self, text):
"""Set the text content."""
def text(self):
"""Get the text content."""
def setColor(self, color):
"""Set the text color."""
def color(self):
"""Get the text color."""
def copy(self):
"""Create a copy of this string."""
def substring(self, start, length=None):
"""Get substring with preserved formatting."""
def split(self, separator):
"""Split string while preserving colors."""
def replace(self, old, new):
"""Replace text while preserving colors."""
def strip(self):
"""Strip whitespace while preserving colors."""
def coloredLength(self):
"""Get length including color escape sequences."""
def plainText(self):
"""Get text without color formatting."""
def toAnsi(self):
"""Convert to ANSI-formatted string."""
# Class methods for formatting
@classmethod
def fromAnsi(cls, ansi_string):
"""Create TTkString from ANSI-formatted string."""
@classmethod
def join(cls, strings, separator=""):
"""Join multiple TTkStrings."""TTkCanvas provides drawing operations for widgets.
class TTkCanvas:
def __init__(self, width=0, height=0):
"""
Initialize a canvas.
Parameters:
- width (int): Canvas width in characters
- height (int): Canvas height in characters
"""
def size(self):
"""Get canvas size as (width, height)."""
def width(self):
"""Get canvas width."""
def height(self):
"""Get canvas height."""
def resize(self, width, height):
"""Resize the canvas."""
def clear(self):
"""Clear the canvas."""
def fill(self, char=' ', color=None):
"""Fill canvas with character and color."""
def drawChar(self, x, y, char, color=None):
"""
Draw a single character.
Parameters:
- x (int): X coordinate
- y (int): Y coordinate
- char (str): Character to draw
- color (TTkColor): Character color
"""
def drawText(self, x, y, text, color=None):
"""
Draw text string.
Parameters:
- x (int): X coordinate
- y (int): Y coordinate
- text (str): Text to draw
- color (TTkColor): Text color
"""
def drawTTkString(self, x, y, ttkString):
"""Draw a TTkString with embedded colors."""
def drawHLine(self, x, y, width, char='-', color=None):
"""Draw horizontal line."""
def drawVLine(self, x, y, height, char='|', color=None):
"""Draw vertical line."""
def drawBox(self, x, y, width, height, color=None):
"""Draw a box outline."""
def fillBox(self, x, y, width, height, char=' ', color=None):
"""Draw a filled box."""
def drawBorder(self, x, y, width, height, border_chars=None, color=None):
"""
Draw border with custom characters.
Parameters:
- x, y: Position
- width, height: Dimensions
- border_chars: Dict with border character definitions
- color: Border color
"""
def copy(self):
"""Create a copy of the canvas."""
def paintCanvas(self, canvas, x=0, y=0):
"""Paint another canvas onto this one."""
def getChar(self, x, y):
"""Get character at position."""
def getColor(self, x, y):
"""Get color at position."""
def boundingRect(self, text):
"""Get bounding rectangle for text."""TTkTheme provides theming capabilities for consistent visual styling.
class TTkTheme:
def __init__(self):
"""Initialize the theme system."""
def setTheme(self, theme_name):
"""Set active theme by name."""
def theme(self):
"""Get current theme name."""
def availableThemes(self):
"""Get list of available themes."""
def addTheme(self, name, theme_data):
"""Add custom theme."""
def getColor(self, element, state="normal"):
"""
Get color for UI element.
Parameters:
- element (str): UI element name (e.g., "button", "window")
- state (str): Element state (e.g., "normal", "hover", "pressed")
"""
def getBorder(self, element):
"""Get border characters for element."""
def getIcon(self, icon_name):
"""Get icon character(s)."""
def setCustomColor(self, element, state, color):
"""Set custom color for element/state."""
def resetToDefault(self):
"""Reset to default theme."""import TermTk as ttk
root = ttk.TTk()
container = ttk.TTkContainer(parent=root)
layout = ttk.TTkVBoxLayout()
# Create colors
red_color = ttk.TTkColor(fg="#FF0000")
green_bg = ttk.TTkColor(bg="#00FF00")
bold_blue = ttk.TTkColor(fg="#0000FF", bold=True)
styled_color = ttk.TTkColor(fg="#FFFF00", bg="#800080", italic=True, underline=True)
# Create labels with different colors
label1 = ttk.TTkLabel(text="Red text", color=red_color)
label2 = ttk.TTkLabel(text="Green background", color=green_bg)
label3 = ttk.TTkLabel(text="Bold blue text", color=bold_blue)
label4 = ttk.TTkLabel(text="Styled text", color=styled_color)
# Predefined colors
label5 = ttk.TTkLabel(text="Predefined red", color=ttk.TTkColor.RED())
label6 = ttk.TTkLabel(text="Predefined cyan", color=ttk.TTkColor.CYAN())
layout.addWidget(label1)
layout.addWidget(label2)
layout.addWidget(label3)
layout.addWidget(label4)
layout.addWidget(label5)
layout.addWidget(label6)
container.setLayout(layout)
root.mainloop()import TermTk as ttk
root = ttk.TTk()
container = ttk.TTkContainer(parent=root)
layout = ttk.TTkVBoxLayout()
# Create colored strings
red_text = ttk.TTkString("Red text", ttk.TTkColor.RED())
blue_text = ttk.TTkString("Blue text", ttk.TTkColor.BLUE())
bold_text = ttk.TTkString("Bold text", ttk.TTkColor(bold=True))
# Combine strings
combined = red_text + " and " + blue_text + " and " + bold_text
# Create label with combined string
label = ttk.TTkLabel()
label.setText(combined)
# Create multi-colored sentence
sentence = ttk.TTkString()
sentence += ttk.TTkString("Hello ", ttk.TTkColor.GREEN())
sentence += ttk.TTkString("colorful ", ttk.TTkColor.YELLOW())
sentence += ttk.TTkString("world!", ttk.TTkColor(fg="#FF69B4", bold=True))
label2 = ttk.TTkLabel()
label2.setText(sentence)
layout.addWidget(label)
layout.addWidget(label2)
container.setLayout(layout)
root.mainloop()import TermTk as ttk
class CustomDrawWidget(ttk.TTkWidget):
def __init__(self, parent=None, **kwargs):
super().__init__(parent=parent, **kwargs)
self.setMinimumSize(40, 20)
def paintEvent(self, canvas):
# Clear canvas
canvas.clear()
# Get dimensions
width = canvas.width()
height = canvas.height()
# Draw border
border_color = ttk.TTkColor(fg="#FFFF00")
canvas.drawBox(0, 0, width, height, border_color)
# Draw title
title = "Custom Drawing"
title_color = ttk.TTkColor(fg="#00FFFF", bold=True)
title_x = (width - len(title)) // 2
canvas.drawText(title_x, 1, title, title_color)
# Draw diagonal lines
line_color = ttk.TTkColor(fg="#FF00FF")
for i in range(min(width-2, height-2)):
canvas.drawChar(i+1, i+2, '\\', line_color)
canvas.drawChar(width-2-i, i+2, '/', line_color)
# Draw filled rectangle
fill_color = ttk.TTkColor(bg="#800000")
canvas.fillBox(5, 5, 10, 5, ' ', fill_color)
# Draw text in rectangle
rect_text_color = ttk.TTkColor(fg="#FFFFFF", bg="#800000")
canvas.drawText(7, 7, "Filled", rect_text_color)
# Draw horizontal and vertical lines
h_line_color = ttk.TTkColor(fg="#00FF00")
v_line_color = ttk.TTkColor(fg="#0000FF")
canvas.drawHLine(1, height//2, width-2, '-', h_line_color)
canvas.drawVLine(width//2, 2, height-3, '|', v_line_color)
# Usage
root = ttk.TTk()
widget = CustomDrawWidget(parent=root)
root.mainloop()import TermTk as ttk
class GradientWidget(ttk.TTkWidget):
def __init__(self, parent=None, **kwargs):
super().__init__(parent=parent, **kwargs)
self.setMinimumSize(50, 15)
# Create gradient
self.gradient = ttk.TTkLinearGradient((0, 0), (50, 0))
self.gradient.addColorStop(0.0, ttk.TTkColor(bg="#FF0000")) # Red
self.gradient.addColorStop(0.33, ttk.TTkColor(bg="#00FF00")) # Green
self.gradient.addColorStop(0.66, ttk.TTkColor(bg="#0000FF")) # Blue
self.gradient.addColorStop(1.0, ttk.TTkColor(bg="#FFFF00")) # Yellow
def paintEvent(self, canvas):
canvas.clear()
width = canvas.width()
height = canvas.height()
# Draw gradient background
for x in range(width):
position = x / (width - 1) if width > 1 else 0
color = self.gradient.colorAt(position)
for y in range(height):
canvas.drawChar(x, y, ' ', color)
# Draw title text
title = "Gradient Background"
title_color = ttk.TTkColor(fg="#FFFFFF", bold=True)
title_x = (width - len(title)) // 2
title_y = height // 2
canvas.drawText(title_x, title_y, title, title_color)
# Usage
root = ttk.TTk()
gradient_widget = GradientWidget(parent=root)
root.mainloop()import TermTk as ttk
class ColorPickerWidget(ttk.TTkWidget):
colorChanged = ttk.pyTTkSignal(ttk.TTkColor)
def __init__(self, parent=None, **kwargs):
super().__init__(parent=parent, **kwargs)
self.setMinimumSize(30, 10)
self.selected_color = ttk.TTkColor.WHITE()
self.colors = [
ttk.TTkColor.BLACK(), ttk.TTkColor.RED(), ttk.TTkColor.GREEN(),
ttk.TTkColor.YELLOW(), ttk.TTkColor.BLUE(), ttk.TTkColor.MAGENTA(),
ttk.TTkColor.CYAN(), ttk.TTkColor.WHITE()
]
def paintEvent(self, canvas):
canvas.clear()
# Draw color swatches
for i, color in enumerate(self.colors):
x = (i % 4) * 6 + 2
y = (i // 4) * 3 + 2
# Draw color swatch
swatch_color = ttk.TTkColor(bg=color.foreground())
canvas.fillBox(x, y, 4, 2, ' ', swatch_color)
# Draw border for selected color
if color == self.selected_color:
border_color = ttk.TTkColor(fg="#FFFFFF")
canvas.drawBox(x-1, y-1, 6, 4, border_color)
def mousePressEvent(self, evt):
# Determine which color was clicked
x = evt.x()
y = evt.y()
col = (x - 2) // 6
row = (y - 2) // 3
if 0 <= col < 4 and 0 <= row < 2:
index = row * 4 + col
if 0 <= index < len(self.colors):
self.selected_color = self.colors[index]
self.colorChanged.emit(self.selected_color)
self.update()
evt.accept()
# Usage
root = ttk.TTk()
container = ttk.TTkContainer(parent=root)
layout = ttk.TTkVBoxLayout()
color_picker = ColorPickerWidget()
sample_label = ttk.TTkLabel(text="Sample Text")
@ttk.pyTTkSlot(ttk.TTkColor)
def color_selected(color):
sample_label.setColor(color)
print(f"Selected color: {color.toAnsi()}")
color_picker.colorChanged.connect(color_selected)
layout.addWidget(ttk.TTkLabel(text="Select a color:"))
layout.addWidget(color_picker)
layout.addWidget(sample_label)
container.setLayout(layout)
root.mainloop()import TermTk as ttk
root = ttk.TTk()
container = ttk.TTkContainer(parent=root)
layout = ttk.TTkVBoxLayout()
# Get theme system
theme = ttk.TTkTheme()
# Create UI elements
title = ttk.TTkLabel(text="Theme Demo")
button1 = ttk.TTkButton(text="Button 1")
button2 = ttk.TTkButton(text="Button 2")
text_edit = ttk.TTkTextEdit()
text_edit.setText("Sample text in editor")
# Theme selector
theme_layout = ttk.TTkHBoxLayout()
theme_label = ttk.TTkLabel(text="Theme:")
theme_combo = ttk.TTkComboBox()
# Add available themes
available_themes = theme.availableThemes()
for theme_name in available_themes:
theme_combo.addItem(theme_name)
theme_layout.addWidget(theme_label)
theme_layout.addWidget(theme_combo)
# Theme change handler
@ttk.pyTTkSlot(str)
def change_theme(theme_name):
theme.setTheme(theme_name)
# Force UI update
root.update()
theme_combo.currentTextChanged.connect(change_theme)
# Add to layout
layout.addLayout(theme_layout)
layout.addWidget(title)
layout.addWidget(button1)
layout.addWidget(button2)
layout.addWidget(text_edit)
container.setLayout(layout)
root.mainloop()Install with Tessl CLI
npx tessl i tessl/pypi-pytermtk