1. Python 文本终端 GUI 框架介绍
Python 文本终端 GUI 框架是一种用于构建命令行用户界面的工具包。它使得开发人员可以使用 Python 语言来构建控制台应用程序,而无需编写复杂的代码。
Python 文本终端 GUI 框架广泛应用于开发各种类型的控制台应用程序,例如配置工具、文本编辑器、数据库管理工具、邮件客户端等。
在本文中,我们将介绍三个Python 文本终端 GUI 框架。
2. Python 文本终端 GUI 框架推荐
2.1. Blessed
Blessed 是一个Python的终端UI工具包,它提供了一些基本的组件,如文本框、选择框、进度条等,以及像下拉列表、多选树、标签页等高级组件。它的特点是功能强大、易于使用和可移植性强。
以下是使用Blessed框架实现的一个简单的“Hello World”程序:
from blessed import Terminal
term = Terminal()
print(term.bold('Hello, world!'))
由于Blessed的功能强大,开发人员可以使用它来实现更高级的功能。例如,以下示例使用Blessed库实现一个非常简单的文本编辑器:
def main():
editor = Editor()
text = editor.edit()
print(text)
class Editor:
def __init__(self, term=None):
if term is None:
term = Terminal()
self.term = term
self.cursor_x = 0
self.cursor_y = 0
self.text = []
def edit(self):
self.draw()
while True:
inp = self.term.inkey()
if inp == '\n':
self.newline()
elif inp == '\t':
self.text[self.cursor_y][self.cursor_x] = ' '
self.cursor_x += 4
self.draw()
elif inp.is_sequence:
self.handle_sequence(inp)
else:
self.handle_char(inp)
def newline(self):
self.cursor_x = 0
self.cursor_y += 1
if self.cursor_y == self.term.height:
del self.text[0]
self.text.append([''] * self.term.width)
else:
self.text.append([''] * self.term.width)
def handle_char(self, inp):
self.text[self.cursor_y][self.cursor_x] = inp
self.cursor_x += 1
if self.cursor_x == self.term.width:
self.cursor_x = 0
self.cursor_y += 1
if self.cursor_y == self.term.height:
del self.text[0]
self.text.append([''] * self.term.width)
else:
self.text.append([''] * self.term.width)
self.draw()
def handle_sequence(self, inp):
if inp.name == 'KEY_BACKSPACE':
self.cursor_x -= 1
if self.cursor_x == -1:
self.cursor_x = self.term.width - 1
self.cursor_y -= 1
if self.cursor_y == -1:
self.cursor_y = 0
self.cursor_x = 0
self.text[self.cursor_y][self.cursor_x] = ''
self.draw()
elif inp.name == 'KEY_LEFT':
self.cursor_x -= 1
if self.cursor_x == -1:
self.cursor_x = self.term.width - 1
self.cursor_y -= 1
if self.cursor_y == -1:
self.cursor_y = 0
self.cursor_x = 0
self.draw()
elif inp.name == 'KEY_RIGHT':
self.cursor_x += 1
if self.cursor_x == self.term.width:
self.cursor_x = 0
self.cursor_y += 1
if self.cursor_y == self.term.height:
del self.text[0]
self.text.append([''] * self.term.width)
else:
self.text.append([''] * self.term.width)
self.draw()
def draw(self):
self.term.clear()
for y, line in enumerate(self.text):
self.term.move(y, 0)
self.term.write(''.join(line))
self.term.move(self.cursor_y, self.cursor_x)
self.term.invisible_cursor()
self.term.refresh()
if __name__ == '__main__':
main()
2.2. Click
Click是一个Python包,用于创建命令行界面(CLI)应用程序。它提供了与argparse不同的方法解析命令行选项,并支持自定义的命令。Click的主要特点是易于使用、快速和功能强大。
以下是使用Click模块实现的一个非常简单的命令行应用程序:
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name', help='The person to greet.')
def hello(count, name):
"""Simple program that greets NAME for a total of COUNT times."""
for _ in range(count):
click.echo(f'Hello, {name}!')
if __name__ == '__main__':
hello()
由于Click是用于构建CLI应用程序的框架,因此它非常适合开发需要处理命令行选项和执行特定任务的工具。例如,以下示例使用Click实现了一个MKV格式转MP4格式的命令行工具:
import click
import shutil
from pathlib import Path
import subprocess
@click.command()
@click.option('--input', prompt='Input file path', help='The input MKV file path.')
@click.option('--output', prompt='Output file path', help='The output MP4 file path.')
def convert(input, output):
"""Convert MKV format to MP4 format using ffmpeg"""
input_path = Path(input)
if not input_path.exists():
click.echo(f"Input file {input} does not exist.")
return
if input_path.suffix != '.mkv':
click.echo(f"Input file {input} is not an MKV file.")
return
output_path = Path(output)
if output_path.suffix != '.mp4':
click.echo(f"Output file {output} is not an MP4 file.")
return
try:
subprocess.check_output(['ffmpeg', '-i', input, '-c:v', 'h264', '-preset', 'ultrafast', '-c:a', 'copy', output])
except subprocess.CalledProcessError as ex:
click.echo(f"Failed to convert file: {ex}")
return
click.echo(f"File conversion complete: {input} -> {output}")
if __name__ == '__main__':
convert()
2.3. Prompt Toolkit
Prompt Toolkit是一个Python 库,它可以用于创建复杂的交互式终端应用程序。它支持高级文本编辑、自动补全、多行输入等功能,还可以创建菜单、选择框、复选框等。
以下是使用Prompt Toolkit实现的一个非常简单的文本编辑器应用程序:
from prompt_toolkit import prompt
from prompt_toolkit.shortcuts import print_formatted_text, PromptSession
from prompt_toolkit.formatted_text import PygmentsTokens, StyleAndTextTuples
from pygments.lexers import PythonLexer
session = PromptSession()
def editor():
text = ''
while True:
line = session.prompt('> ')
if line == 'exit':
break
text += f'{line}\n'
print_formatted_text(StyleAndTextTuples([('class:pygments.py', text)]), style=PygmentsTokens, lexer=PythonLexer)
if __name__ == '__main__':
editor()
由于Prompt Toolkit支持高级文本编辑、自动补全、多行输入等功能,因此它非常适合开发复杂的终端应用程序。例如,以下示例使用Prompt Toolkit创建了一个简单的文件浏览器:
import os
import sys
from prompt_toolkit import prompt, print_formatted_text
from prompt_toolkit.shortcuts import ProgressBar
from prompt_toolkit.shortcuts import checkboxlist_dialog, input_dialog, radiolist_dialog
from prompt_toolkit.completion import WordCompleter
from prompt_toolkit.styles import Style
from pathlib import Path
FILE_TYPES = ['all', 'directory', 'file']
file_types_completer = WordCompleter(FILE_TYPES)
sort_by_completer = WordCompleter(['name', 'date', 'size'])
def list_files(directory, filetype=None, sort_by=None):
files = []
directory = Path(directory)
for file in directory.iterdir():
if str(file).startswith('.'):
continue
if filetype == 'directory' and not file.is_dir():
continue
elif filetype == 'file' and not file.is_file():
continue
files.append(file)
if sort_by == 'name':
files.sort(key=lambda f: f.name.lower())
elif sort_by == 'date':
files.sort(key=lambda f: f.stat().st_mtime)
elif sort_by == 'size':
files.sort(key=lambda f: f.stat().st_size)
return files
def main(directory):
style = Style.from_dict({
'progress-bar': 'bg:#f44',
})
while True:
files = list_files(directory)
choices = [{'name': '.. (up one level)', 'checked': False}]
for file in files:
if file.is_dir():
choices.append({'name': f'{file.name}/', 'checked': False})
else:
choices.append({'name': file.name, 'checked': False})
results = checkboxlist_dialog(
title='File Browser',
text='Select files to view, edit, or delete:',
values=choices,
).run()
if not results:
break
for result in results:
file = files[result - 1]
if file.is_dir():
directory = file
break
else:
with open(file, 'r') as f:
contents = f.read()
result = radiolist_dialog(
title='File Contents',
text=f'View or edit the contents of {file.name}:',
values=[
{'name': 'View', 'value': 'view', 'checked': True},
{'name': 'Edit', 'value': 'edit'},
],
).run()
if result == 'view':
print_formatted_text(contents)
else:
new_contents = input_dialog(
title=f'Edit {file.name}',
text='Enter new text:',default=contents,
).run()
with open(file, 'w') as f:
f.write(new_contents)
print(f'{file.name} saved.')
print(f'Current directory: {directory}')
if __name__ == '__main__':
directory = Path('.')
main(directory)
3. 结论
三个Python 文本终端 GUI 框架:Blessed、Click、Prompt Toolkit 拥有不同的特点,能够满足不同类型的终端需求。Blessed适合开发各种类型的控制台应用程序,包括文本编辑器、配置工具、邮件客户端等。Click用于构建命令行界面(CLI)应用程序,非常适合开发需要处理命令行选项和执行特定任务的工具。Prompt Toolkit是一个灵活的Python库,它可以用于创建复杂的交互式终端应用程序。