pyTermTk
Pythonのターミナルツールキットライブラリ。Qt風のAPIを提供し、レイアウトマネージャー、シグナル・スロット機能を備えた本格的なTUIフレームワークです。
GitHub概要
ceccopierangiolieugenio/pyTermTk
Python Terminal Toolkit - a Spiced Up Cross Compatible TUI Library 🌶️
スター744
ウォッチ7
フォーク31
作成日:2021年2月16日
言語:Python
ライセンス:MIT License
トピックス
asciiascii-graphicslibrarypyodidepytermtkpythonterminalterminal-emulatorterminal-graphicsterminal-multiplexertext-editortuitui-apptui-editortui-librarytutorialuiui-designui-libraryuser-interface
スター履歴
データ取得日時: 2025/7/25 06:23
pyTermTk
pyTermTkは、Pythonのターミナルツールキットライブラリです。Qt風のAPIを採用し、シグナル・スロット機能、レイアウトマネージャー、イベント駆動型プログラミングを提供する本格的なTUIフレームワークです。デスクトップアプリケーション開発者にとって親しみやすい設計となっています。
主な特徴
Qt風API
- 親しみやすい設計: QtライクなAPIで学習コストを削減
- オブジェクト指向: クラスベースの設計思想
- 一貫性: Qtと類似したメソッド名と構造
シグナル・スロット
- イベント駆動: シグナルとスロットによる疎結合
- カスタムシグナル: 独自のシグナル定義が可能
- 非同期処理: 効率的なイベント処理
レイアウト管理
- 自動配置: 動的なウィジェット配置
- サイズ調整: 自動的なサイズ計算
- ネスト構造: 複雑なレイアウトの構築
インストール
pip install pyTermTk
基本的な使用方法
シンプルなアプリケーション
#!/usr/bin/env python3
import TermTk as ttk
root = ttk.TTk()
# メインウィンドウの作成
win = ttk.TTkWindow(parent=root, pos=(1,1), size=(50,20), title="Hello pyTermTk")
# ラベルウィジェットの追加
label = ttk.TTkLabel(parent=win, pos=(2,2), text="Hello, World!")
# ボタンの追加
button = ttk.TTkButton(parent=win, pos=(2,4), text="Click Me!")
def button_clicked():
label.setText("Button Clicked!")
# シグナル・スロット接続
button.clicked.connect(button_clicked)
root.mainloop()
レイアウトマネージャーの使用
#!/usr/bin/env python3
import TermTk as ttk
root = ttk.TTk()
# メインウィンドウ
win = ttk.TTkWindow(parent=root, pos=(1,1), size=(60,25), title="Layout Example")
# 垂直レイアウト
vbox = ttk.TTkVBoxLayout()
win.setLayout(vbox)
# ヘッダー
header = ttk.TTkLabel(text="pyTermTk Layout Example")
vbox.addWidget(header)
# 水平レイアウト
hbox = ttk.TTkHBoxLayout()
# 左側パネル
left_panel = ttk.TTkFrame()
left_layout = ttk.TTkVBoxLayout()
left_panel.setLayout(left_layout)
left_layout.addWidget(ttk.TTkLabel(text="Left Panel"))
left_layout.addWidget(ttk.TTkButton(text="Button 1"))
left_layout.addWidget(ttk.TTkButton(text="Button 2"))
# 右側パネル
right_panel = ttk.TTkFrame()
right_layout = ttk.TTkVBoxLayout()
right_panel.setLayout(right_layout)
right_layout.addWidget(ttk.TTkLabel(text="Right Panel"))
right_layout.addWidget(ttk.TTkLineEdit())
right_layout.addWidget(ttk.TTkTextEdit())
hbox.addWidget(left_panel)
hbox.addWidget(right_panel)
vbox.addLayout(hbox)
# フッター
footer = ttk.TTkLabel(text="Status: Ready")
vbox.addWidget(footer)
root.mainloop()
高度な機能
カスタムウィジェット
#!/usr/bin/env python3
import TermTk as ttk
class CounterWidget(ttk.TTkWidget):
# カスタムシグナル定義
valueChanged = ttk.pyTTkSignal(int)
def __init__(self, initial_value=0, **kwargs):
super().__init__(**kwargs)
self._value = initial_value
# レイアウト設定
layout = ttk.TTkHBoxLayout()
self.setLayout(layout)
# コンポーネント
self._label = ttk.TTkLabel(text=f"Count: {self._value}")
self._dec_btn = ttk.TTkButton(text="-")
self._inc_btn = ttk.TTkButton(text="+")
layout.addWidget(self._dec_btn)
layout.addWidget(self._label)
layout.addWidget(self._inc_btn)
# シグナル接続
self._inc_btn.clicked.connect(self._increment)
self._dec_btn.clicked.connect(self._decrement)
def _increment(self):
self._value += 1
self._update_display()
self.valueChanged.emit(self._value)
def _decrement(self):
self._value -= 1
self._update_display()
self.valueChanged.emit(self._value)
def _update_display(self):
self._label.setText(f"Count: {self._value}")
def value(self):
return self._value
def setValue(self, value):
self._value = value
self._update_display()
self.valueChanged.emit(self._value)
# カスタムウィジェットの使用
root = ttk.TTk()
win = ttk.TTkWindow(parent=root, pos=(1,1), size=(50,15), title="Custom Widget")
layout = ttk.TTkVBoxLayout()
win.setLayout(layout)
counter = CounterWidget(initial_value=10)
status_label = ttk.TTkLabel(text="Value: 10")
def on_value_changed(value):
status_label.setText(f"Value: {value}")
counter.valueChanged.connect(on_value_changed)
layout.addWidget(counter)
layout.addWidget(status_label)
root.mainloop()
タブとメニュー
#!/usr/bin/env python3
import TermTk as ttk
root = ttk.TTk()
# メインウィンドウ
win = ttk.TTkWindow(parent=root, pos=(1,1), size=(70,30), title="Tabs and Menus")
# メニューバー
menubar = ttk.TTkMenuBar(parent=win)
# ファイルメニュー
file_menu = menubar.addMenu("File")
file_menu.addAction("New").triggered.connect(lambda: print("New file"))
file_menu.addAction("Open").triggered.connect(lambda: print("Open file"))
file_menu.addSeparator()
file_menu.addAction("Exit").triggered.connect(root.quit)
# 編集メニュー
edit_menu = menubar.addMenu("Edit")
edit_menu.addAction("Copy").triggered.connect(lambda: print("Copy"))
edit_menu.addAction("Paste").triggered.connect(lambda: print("Paste"))
# タブウィジェット
tab_widget = ttk.TTkTabWidget(parent=win, pos=(0,1), size=(70,28))
# タブ1: テキストエディタ
tab1 = ttk.TTkWidget()
tab1_layout = ttk.TTkVBoxLayout()
tab1.setLayout(tab1_layout)
text_edit = ttk.TTkTextEdit()
tab1_layout.addWidget(ttk.TTkLabel(text="Text Editor Tab"))
tab1_layout.addWidget(text_edit)
tab_widget.addTab(tab1, "Editor")
# タブ2: 設定
tab2 = ttk.TTkWidget()
tab2_layout = ttk.TTkVBoxLayout()
tab2.setLayout(tab2_layout)
tab2_layout.addWidget(ttk.TTkLabel(text="Settings Tab"))
tab2_layout.addWidget(ttk.TTkCheckbox(text="Enable feature A"))
tab2_layout.addWidget(ttk.TTkCheckbox(text="Enable feature B"))
combo = ttk.TTkComboBox()
combo.addItems(["Option 1", "Option 2", "Option 3"])
tab2_layout.addWidget(combo)
tab_widget.addTab(tab2, "Settings")
# タブ3: 情報
tab3 = ttk.TTkWidget()
tab3_layout = ttk.TTkVBoxLayout()
tab3.setLayout(tab3_layout)
tab3_layout.addWidget(ttk.TTkLabel(text="Information Tab"))
tab3_layout.addWidget(ttk.TTkLabel(text="pyTermTk Version: 0.x.x"))
tab3_layout.addWidget(ttk.TTkLabel(text="Platform: Terminal"))
tab_widget.addTab(tab3, "Info")
root.mainloop()
ダイアログとポップアップ
#!/usr/bin/env python3
import TermTk as ttk
class MainWindow(ttk.TTkWindow):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = ttk.TTkVBoxLayout()
self.setLayout(layout)
# ボタン群
msg_btn = ttk.TTkButton(text="Show Message")
input_btn = ttk.TTkButton(text="Show Input Dialog")
confirm_btn = ttk.TTkButton(text="Show Confirmation")
layout.addWidget(ttk.TTkLabel(text="Dialog Examples"))
layout.addWidget(msg_btn)
layout.addWidget(input_btn)
layout.addWidget(confirm_btn)
# 結果表示
self.result_label = ttk.TTkLabel(text="Result will appear here")
layout.addWidget(self.result_label)
# シグナル接続
msg_btn.clicked.connect(self.show_message)
input_btn.clicked.connect(self.show_input_dialog)
confirm_btn.clicked.connect(self.show_confirmation)
def show_message(self):
dialog = ttk.TTkMessageBox(
parent=self,
title="Information",
text="This is a message dialog!"
)
dialog.exec()
self.result_label.setText("Message dialog shown")
def show_input_dialog(self):
dialog = ttk.TTkInputDialog(
parent=self,
title="Input",
label="Enter your name:"
)
if dialog.exec() == ttk.TTkK.Accepted:
text = dialog.textValue()
self.result_label.setText(f"Input: {text}")
else:
self.result_label.setText("Input canceled")
def show_confirmation(self):
dialog = ttk.TTkMessageBox(
parent=self,
title="Confirmation",
text="Are you sure?",
standardButtons=ttk.TTkMessageBox.Yes | ttk.TTkMessageBox.No
)
result = dialog.exec()
if result == ttk.TTkMessageBox.Yes:
self.result_label.setText("Confirmed: Yes")
else:
self.result_label.setText("Confirmed: No")
root = ttk.TTk()
win = MainWindow(parent=root, pos=(1,1), size=(60,20), title="Dialog Example")
root.mainloop()
他のライブラリとの比較
特徴 | pyTermTk | Textual | Urwid | PyTermGUI |
---|---|---|---|---|
API設計 | Qt風 | 独自 | 独自 | YAML風 |
レイアウト | 自動 | CSS風 | 手動 | 設定 |
シグナル・スロット | ○ | × | × | × |
学習コスト | Qt経験者は低 | 中 | 高 | 中 |
機能の豊富さ | 高 | 高 | 高 | 中 |
使用事例
- Qt移植: Qtアプリケーションのターミナル版
- 複雑なTUIアプリ: 多機能なターミナルアプリケーション
- 開発ツール: IDE風のターミナルツール
- 管理画面: システム管理用のTUIツール
コミュニティとサポート
- 開発: アクティブな開発が継続中
- ドキュメント: 充実したAPIリファレンス
- 例題: Qt経験者向けのサンプル
- Qt互換性: Qt APIとの高い親和性
pyTermTkは、Qt開発者にとって親しみやすいAPIを提供し、本格的なTUIアプリケーション開発を可能にする現代的なフレームワークです。