是否可以使用提示获取用户输入within使用 Python Rich 的布局元素?
我的目标是使用 Rich 的 Layout 构建一个具有 4 个窗格的全屏窗口。顶部 3 个包含标题、成分和方法,效果很好,但我希望底部一个包含用户输入的提示。
期望的输出:
用户输入的文本显示在布局的底部面板内。
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ │
│ Chocolate cheesecake │
│ │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────── 'ingredients' (58 x 7) ────────────────┐┌─────────────────── 'method' (59 x 7) ───────────────────┐
│ ││ │
│ ││ │
│ Layout(name='ingredients') ││ Layout(name='method') │
│ ││ │
│ ││ │
└────────────────────────────────────────────────────────┘└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────── Search for a recipe ───────────────────────────────────────────────┐
│ │
│ > : │
│ │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
我的尝试:
from rich import print
from rich.panel import Panel
from rich.layout import Layout
from rich.prompt import Prompt
def rich_ui():
while True:
layout = Layout()
layout.split_column(
Layout(name="banner"),
Layout(name="recipe"),
Layout(name="search")
)
layout['banner'].update(Panel('Chocolate cheesecake', padding=1))
layout['banner'].size = 5
layout['recipe'].split_row(
Layout(name="ingredients"),
Layout(name="method")
)
layout['search'].update(Panel(Prompt.ask('> '), title='Search for a recipe'))
layout['search'].size = 5
print(layout)
if __name__ == '__main__':
rich_ui()
实际输出:
注意提示的>:
位于布局部分之外。
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ │
│ Chocolate cheesecake │
│ │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────── 'ingredients' (58 x 7) ────────────────┐┌─────────────────── 'method' (59 x 7) ───────────────────┐
│ ││ │
│ ││ │
│ Layout(name='ingredients') ││ Layout(name='method') │
│ ││ │
│ ││ │
└────────────────────────────────────────────────────────┘└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────── Search for a recipe ───────────────────────────────────────────────┐
│ │
│ │
│ │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
> :
这也是可能的,而且可以说更容易做到Textual https://github.com/Textualize/textual如果您愿意将其用于基于文本的 GUI。我喜欢它来满足我的需要,但是@威尔·麦古根 https://stackoverflow.com/users/673463/will-mcgugan可能对 Textual 的未来有话要说。
您只需实现一个新的小部件作为文本输入控件,但对于一个简单的小部件来说,代码并不多。您可以使用 Textual 本身的键盘输入机制。
像这样的东西:
class InputBox(Widget):
"""takes typed input mostly for debugging"""
has_focus: Reactive[bool] = Reactive(False)
style: Reactive[str] = Reactive("")
height: Reactive[int or None] = Reactive(None)
text: Reactive[str] = Reactive("")
def __init__(self, *, name: str or None = None, height: int or None = None, callback: Callable[[str], None] = None) -> None:
super().__init__(name=name)
self.height = height
self.callback = callback
def render(self) -> Panel:
return Panel(
self.text,
title=self.name,
box=box.HEAVY if self.has_focus else box.ROUNDED,
style="cyan" if self.has_focus else "dim white",
height=self.height,
highlight=True
)
async def on_focus(self, event: events.Focus) -> None:
self.has_focus = True
async def on_blur(self, event: events.Blur) -> None:
self.has_focus = False
async def on_key(self, event: events.Key) -> None:
"""Handle key presses."""
self.log(event)
if event.key == "ctrl+h":
self.text = self.text[:-1]
elif event.key == "enter":
# process input
if self.callback:
self.callback(self.text)
self.text = ""
elif len(event.key) == 1:
self.text += str(event.key)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)