Python Terminal Toolkit for creating sophisticated text-based user interfaces with Qt-like API and full widget support
—
Multi-line text editing capabilities with syntax highlighting, line numbers, and advanced text manipulation features.
TTkTextEdit provides comprehensive multi-line text editing functionality.
class TTkTextEdit(TTkAbstractScrollArea):
def __init__(self, parent=None, **kwargs):
"""
Initialize a text edit widget.
Parameters:
- text (str): Initial text content
- readOnly (bool): Whether the editor is read-only
- lineWrapMode (int): Line wrapping mode
- wordWrapMode (int): Word wrapping mode
"""
def setText(self, text):
"""Set the text content."""
def text(self):
"""Get the text content."""
def append(self, text):
"""Append text to the end."""
def prepend(self, text):
"""Prepend text to the beginning."""
def insertText(self, text):
"""Insert text at cursor position."""
def clear(self):
"""Clear all text."""
def copy(self):
"""Copy selected text to clipboard."""
def cut(self):
"""Cut selected text to clipboard."""
def paste(self):
"""Paste text from clipboard."""
def undo(self):
"""Undo last operation."""
def redo(self):
"""Redo last undone operation."""
def selectAll(self):
"""Select all text."""
def setReadOnly(self, readOnly):
"""Set read-only mode."""
def isReadOnly(self):
"""Check if in read-only mode."""
def setLineWrapMode(self, mode):
"""Set line wrapping mode."""
def lineWrapMode(self):
"""Get line wrapping mode."""
def setWordWrapMode(self, mode):
"""Set word wrapping mode."""
def wordWrapMode(self):
"""Get word wrapping mode."""
def textCursor(self):
"""Get the text cursor."""
def setTextCursor(self, cursor):
"""Set the text cursor."""
def cursorPosition(self):
"""Get cursor position."""
def setCursorPosition(self, position):
"""Set cursor position."""
def hasSelectedText(self):
"""Check if text is selected."""
def selectedText(self):
"""Get selected text."""
def find(self, text, options=0):
"""Find text in the document."""
def replace(self, text):
"""Replace selected text."""
def setDocument(self, document):
"""Set the text document."""
def document(self):
"""Get the text document."""
def setTabStopWidth(self, width):
"""Set tab stop width."""
def tabStopWidth(self):
"""Get tab stop width."""
def isUndoRedoEnabled(self):
"""Check if undo/redo is enabled."""
def setUndoRedoEnabled(self, enabled):
"""Enable/disable undo/redo."""
# Signals
textChanged: pyTTkSignal # Emitted when text changes
cursorPositionChanged: pyTTkSignal # Emitted when cursor moves
selectionChanged: pyTTkSignal # Emitted when selection changes
undoAvailable: pyTTkSignal # Emitted when undo becomes available
redoAvailable: pyTTkSignal # Emitted when redo becomes availableTTkTextEditView provides the visual component of the text editor.
class TTkTextEditView(TTkWidget):
def __init__(self, parent=None, **kwargs):
"""Initialize a text edit view."""
def setDocument(self, document):
"""Set the text document to display."""
def document(self):
"""Get the current document."""
def setTextCursor(self, cursor):
"""Set the text cursor."""
def textCursor(self):
"""Get the text cursor."""
def setLineNumberEnabled(self, enabled):
"""Enable/disable line numbers."""
def isLineNumberEnabled(self):
"""Check if line numbers are enabled."""
def setSyntaxHighlighter(self, highlighter):
"""Set syntax highlighter."""
def syntaxHighlighter(self):
"""Get syntax highlighter."""TTkTextEditRuler provides line numbers and editor annotations.
class TTkTextEditRuler(TTkWidget):
def __init__(self, parent=None, **kwargs):
"""Initialize a text edit ruler."""
def setTextEdit(self, textEdit):
"""Set the associated text edit widget."""
def textEdit(self):
"""Get the associated text edit widget."""
def setLineNumbersVisible(self, visible):
"""Show/hide line numbers."""
def lineNumbersVisible(self):
"""Check if line numbers are visible."""
def setBookmarksEnabled(self, enabled):
"""Enable/disable bookmark support."""
def bookmarksEnabled(self):
"""Check if bookmarks are enabled."""
def addBookmark(self, line):
"""Add bookmark at line."""
def removeBookmark(self, line):
"""Remove bookmark from line."""
def hasBookmark(self, line):
"""Check if line has bookmark."""
def bookmarks(self):
"""Get list of bookmarked lines."""TTkTextCursor provides navigation and text manipulation within documents.
class TTkTextCursor:
def __init__(self, document=None):
"""
Initialize a text cursor.
Parameters:
- document: Text document to operate on
"""
def position(self):
"""Get cursor position."""
def setPosition(self, position, mode=None):
"""
Set cursor position.
Parameters:
- position (int): Character position
- mode: Selection mode (MoveAnchor, KeepAnchor)
"""
def movePosition(self, operation, mode=None, n=1):
"""
Move cursor by operation.
Parameters:
- operation: Move operation (Start, End, Up, Down, etc.)
- mode: Selection mode
- n: Number of operations
"""
def hasSelection(self):
"""Check if cursor has selection."""
def selectedText(self):
"""Get selected text."""
def selectionStart(self):
"""Get selection start position."""
def selectionEnd(self):
"""Get selection end position."""
def clearSelection(self):
"""Clear current selection."""
def select(self, selection):
"""Select text by selection type."""
def insertText(self, text):
"""Insert text at cursor position."""
def deleteChar(self):
"""Delete character at cursor."""
def deletePreviousChar(self):
"""Delete character before cursor."""
def beginEditBlock(self):
"""Begin an edit block for undo/redo."""
def endEditBlock(self):
"""End an edit block."""
def atStart(self):
"""Check if cursor is at document start."""
def atEnd(self):
"""Check if cursor is at document end."""
def atBlockStart(self):
"""Check if cursor is at block start."""
def atBlockEnd(self):
"""Check if cursor is at block end."""TTkTextDocument represents the document model for text editing.
class TTkTextDocument:
def __init__(self, parent=None):
"""Initialize a text document."""
def setPlainText(self, text):
"""Set document content as plain text."""
def toPlainText(self):
"""Get document content as plain text."""
def isEmpty(self):
"""Check if document is empty."""
def blockCount(self):
"""Get number of text blocks."""
def characterCount(self):
"""Get total character count."""
def lineCount(self):
"""Get number of lines."""
def findBlock(self, position):
"""Find text block at position."""
def findBlockByLineNumber(self, lineNumber):
"""Find text block by line number."""
def isModified(self):
"""Check if document is modified."""
def setModified(self, modified=True):
"""Set document modified state."""
def undo(self):
"""Undo last operation."""
def redo(self):
"""Redo last undone operation."""
def isUndoAvailable(self):
"""Check if undo is available."""
def isRedoAvailable(self):
"""Check if redo is available."""
def setUndoRedoEnabled(self, enabled):
"""Enable/disable undo/redo."""
def isUndoRedoEnabled(self):
"""Check if undo/redo is enabled."""
def clear(self):
"""Clear document content."""
# Signals
contentsChanged: pyTTkSignal # Emitted when content changes
modificationChanged: pyTTkSignal # Emitted when modification state changes
undoAvailable: pyTTkSignal # Emitted when undo availability changes
redoAvailable: pyTTkSignal # Emitted when redo availability changesTextDocumentHighlight provides syntax highlighting capabilities.
class TextDocumentHighlight:
def __init__(self, parent=None):
"""Initialize syntax highlighter."""
def setDocument(self, document):
"""Set document to highlight."""
def document(self):
"""Get highlighted document."""
def highlightBlock(self, text):
"""Override to implement custom highlighting."""
def setFormat(self, start, count, format):
"""Set formatting for text range."""
def format(self, position):
"""Get format at position."""
def setDefaultColor(self, color):
"""Set default text color."""
def defaultColor(self):
"""Get default text color."""
def addKeyword(self, keyword, color):
"""Add keyword with color."""
def addPattern(self, pattern, color):
"""Add regex pattern with color."""
def setCommentColor(self, color):
"""Set comment color."""
def setStringColor(self, color):
"""Set string literal color."""
def setNumberColor(self, color):
"""Set number literal color."""import TermTk as ttk
root = ttk.TTk()
container = ttk.TTkContainer(parent=root)
layout = ttk.TTkVBoxLayout()
# Create text editor
text_edit = ttk.TTkTextEdit()
initial_text = """# Welcome to pyTermTk Text Editor
This is a multi-line text editor with the following features:
- Syntax highlighting
- Line numbers
- Undo/Redo support
- Find and replace
- Cut, copy, paste operations
Type your text here..."""
text_edit.setText(initial_text)
# Create toolbar
toolbar_layout = ttk.TTkHBoxLayout()
save_btn = ttk.TTkButton(text="Save")
load_btn = ttk.TTkButton(text="Load")
undo_btn = ttk.TTkButton(text="Undo")
redo_btn = ttk.TTkButton(text="Redo")
find_btn = ttk.TTkButton(text="Find")
toolbar_layout.addWidget(save_btn)
toolbar_layout.addWidget(load_btn)
toolbar_layout.addWidget(undo_btn)
toolbar_layout.addWidget(redo_btn)
toolbar_layout.addWidget(find_btn)
toolbar_layout.addStretch(1)
# Status bar
status = ttk.TTkLabel(text="Ready")
# Button handlers
@ttk.pyTTkSlot()
def save_file():
text = text_edit.text()
# Save logic here
status.setText("File saved")
@ttk.pyTTkSlot()
def undo_action():
text_edit.undo()
@ttk.pyTTkSlot()
def redo_action():
text_edit.redo()
# Connect buttons
save_btn.clicked.connect(save_file)
undo_btn.clicked.connect(undo_action)
redo_btn.clicked.connect(redo_action)
# Text change handler
@ttk.pyTTkSlot()
def text_changed():
status.setText("Modified")
text_edit.textChanged.connect(text_changed)
# Add to layout
layout.addLayout(toolbar_layout)
layout.addWidget(text_edit)
layout.addWidget(status)
container.setLayout(layout)
root.mainloop()import TermTk as ttk
root = ttk.TTk()
container = ttk.TTkContainer(parent=root)
layout = ttk.TTkHBoxLayout()
# Create text editor with ruler
text_edit = ttk.TTkTextEdit()
ruler = ttk.TTkTextEditRuler()
# Associate ruler with text editor
ruler.setTextEdit(text_edit)
ruler.setLineNumbersVisible(True)
ruler.setBookmarksEnabled(True)
# Sample code content
code_content = """#!/usr/bin/env python3
import TermTk as ttk
def main():
root = ttk.TTk()
# Create main window
window = ttk.TTkWindow(
parent=root,
title="My App",
size=(60, 20)
)
# Add widgets
label = ttk.TTkLabel(
parent=window,
text="Hello World!"
)
root.mainloop()
if __name__ == "__main__":
main()"""
text_edit.setText(code_content)
# Add bookmarks to some lines
ruler.addBookmark(1) # Bookmark shebang line
ruler.addBookmark(8) # Bookmark main window creation
layout.addWidget(ruler)
layout.addWidget(text_edit, stretch=1)
container.setLayout(layout)
root.mainloop()import TermTk as ttk
class FindReplaceDialog(ttk.TTkWindow):
def __init__(self, parent=None, text_edit=None):
super().__init__(parent=parent, title="Find & Replace", size=(40, 15))
self.text_edit = text_edit
layout = ttk.TTkVBoxLayout()
# Find section
find_layout = ttk.TTkHBoxLayout()
find_layout.addWidget(ttk.TTkLabel(text="Find:"))
self.find_edit = ttk.TTkLineEdit()
find_layout.addWidget(self.find_edit)
# Replace section
replace_layout = ttk.TTkHBoxLayout()
replace_layout.addWidget(ttk.TTkLabel(text="Replace:"))
self.replace_edit = ttk.TTkLineEdit()
replace_layout.addWidget(self.replace_edit)
# Options
self.case_sensitive = ttk.TTkCheckbox(text="Case sensitive")
self.whole_words = ttk.TTkCheckbox(text="Whole words only")
# Buttons
btn_layout = ttk.TTkHBoxLayout()
find_btn = ttk.TTkButton(text="Find Next")
replace_btn = ttk.TTkButton(text="Replace")
replace_all_btn = ttk.TTkButton(text="Replace All")
close_btn = ttk.TTkButton(text="Close")
btn_layout.addWidget(find_btn)
btn_layout.addWidget(replace_btn)
btn_layout.addWidget(replace_all_btn)
btn_layout.addWidget(close_btn)
# Add to layout
layout.addLayout(find_layout)
layout.addLayout(replace_layout)
layout.addWidget(self.case_sensitive)
layout.addWidget(self.whole_words)
layout.addLayout(btn_layout)
self.setLayout(layout)
# Connect buttons
find_btn.clicked.connect(self.find_next)
replace_btn.clicked.connect(self.replace_current)
replace_all_btn.clicked.connect(self.replace_all)
close_btn.clicked.connect(self.close)
@ttk.pyTTkSlot()
def find_next(self):
if self.text_edit:
find_text = self.find_edit.text()
options = 0
if self.case_sensitive.isChecked():
options |= ttk.TTkConstant.FindCaseSensitively
if self.whole_words.isChecked():
options |= ttk.TTkConstant.FindWholeWords
found = self.text_edit.find(find_text, options)
if not found:
print("Text not found")
@ttk.pyTTkSlot()
def replace_current(self):
if self.text_edit and self.text_edit.hasSelectedText():
replace_text = self.replace_edit.text()
self.text_edit.replace(replace_text)
@ttk.pyTTkSlot()
def replace_all(self):
if self.text_edit:
find_text = self.find_edit.text()
replace_text = self.replace_edit.text()
# Simple replace all implementation
content = self.text_edit.text()
if not self.case_sensitive.isChecked():
# Case insensitive replace
content = content.replace(find_text.lower(), replace_text)
else:
content = content.replace(find_text, replace_text)
self.text_edit.setText(content)
# Usage example
root = ttk.TTk()
container = ttk.TTkContainer(parent=root)
layout = ttk.TTkVBoxLayout()
text_edit = ttk.TTkTextEdit()
text_edit.setText("This is sample text. Find and replace this text.")
find_replace_btn = ttk.TTkButton(text="Find & Replace")
@ttk.pyTTkSlot()
def open_find_replace():
dialog = FindReplaceDialog(parent=root, text_edit=text_edit)
dialog.show()
find_replace_btn.clicked.connect(open_find_replace)
layout.addWidget(find_replace_btn)
layout.addWidget(text_edit)
container.setLayout(layout)
root.mainloop()import TermTk as ttk
class PythonSyntaxHighlighter(ttk.TextDocumentHighlight):
def __init__(self, parent=None):
super().__init__(parent=parent)
# Define colors
self.keyword_color = ttk.TTkColor(fg="#0066CC")
self.comment_color = ttk.TTkColor(fg="#008000")
self.string_color = ttk.TTkColor(fg="#AA0000")
self.number_color = ttk.TTkColor(fg="#FF6600")
# Python keywords
self.keywords = [
'def', 'class', 'import', 'from', 'if', 'else', 'elif',
'for', 'while', 'try', 'except', 'finally', 'with',
'return', 'yield', 'pass', 'break', 'continue',
'and', 'or', 'not', 'in', 'is', 'None', 'True', 'False'
]
def highlightBlock(self, text):
# Highlight keywords
for keyword in self.keywords:
index = text.find(keyword)
while index >= 0:
# Check if it's a whole word
if (index == 0 or not text[index-1].isalnum()) and \
(index + len(keyword) >= len(text) or not text[index + len(keyword)].isalnum()):
self.setFormat(index, len(keyword), self.keyword_color)
index = text.find(keyword, index + 1)
# Highlight comments
comment_index = text.find('#')
if comment_index >= 0:
self.setFormat(comment_index, len(text) - comment_index, self.comment_color)
# Highlight strings
for quote in ['"', "'"]:
start = 0
while True:
start = text.find(quote, start)
if start == -1:
break
end = text.find(quote, start + 1)
if end == -1:
end = len(text)
else:
end += 1
self.setFormat(start, end - start, self.string_color)
start = end
# Create code editor with syntax highlighting
root = ttk.TTk()
container = ttk.TTkContainer(parent=root)
text_edit = ttk.TTkTextEdit()
highlighter = PythonSyntaxHighlighter()
text_edit.setSyntaxHighlighter(highlighter)
sample_code = '''def factorial(n):
"""Calculate factorial of n"""
if n <= 1:
return 1
else:
return n * factorial(n - 1)
# Test the function
result = factorial(5)
print(f"Factorial of 5 is {result}")'''
text_edit.setText(sample_code)
container.addWidget(text_edit)
root.mainloop()Install with Tessl CLI
npx tessl i tessl/pypi-pytermtk