在文本应用中,回车键的绑定不起作用
我有一个 textual 应用,大致是这样的:
class ToDoApp(App):
BINDINGS = [
Binding(key="q", action="quit", description="Quit the app"),
Binding(
key="question_mark",
action="help",
description="Show help screen",
key_display="?",
),
Binding(key="n", action="new", description="New ToDo", show=True),
Binding(key="d", action="delete", description="Delete ToDo", show=True),
Binding(key="j", action="down", description="Scroll down", show=True),
Binding(key="k", action="up", description="Scroll up", show=True),
Binding(key="enter", action="select", description="Select", show=True),
]
...
def action_select(self) -> None:
if self.focused == OptionList:
self.query_one(SelectionList).focus()
其他绑定都能工作,但不知为何 enter 绑定不起作用。调试时我发现它从不进入 action_select 函数。
可能是什么问题?
解决方案
我发现了两个问题:
Enter可能已经绑定到应用程序或小部件上,对新的绑定可能没有反应。与ChatGPT交流后,我发现它可能需要在Binding中使用priority=True
Binding("enter", "select", "Select", priority=True)
self.focused == OptionList不起作用,它需要使用isinstance()
if isinstance(self.focused, OptionList):
self.query_one(SelectionList).focus()
完整可运行的代码:
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.widgets import OptionList, SelectionList, Footer
class ToDoApp(App):
BINDINGS = [
Binding("q", "quit", "Quit", show=True),
Binding("n", "new", "New ToDo", show=True),
Binding("d", "delete", "Delete ToDo", show=True),
Binding("j", "down", "Scroll down", show=True),
Binding("k", "up", "Scroll up", show=True),
# Binding("l", "select", "Select", show=True), # to check if function is working
Binding("enter", "select", "Select", show=True, priority=True),
]
def compose(self) -> ComposeResult:
yield OptionList("Task 1", "Task 2", "Task 3")
yield SelectionList(("Done 1", 1), ("Done 2", 2))
# yield Footer()
def action_select(self) -> None:
# if self.focused == OptionList:
# self.query_one(SelectionList).focus()
if isinstance(self.focused, OptionList):
self.query_one(SelectionList).focus()
if __name__ == "__main__":
ToDoApp().run()
编辑:
似乎有一种更好的方法,在按下 enter 于 OptionList 时就用 on_option_list_option_selected 在 OptionList 上运行代码(无需绑定)
这个函数接收 event,其中包含关于在 OptionList 上被按下的选项的信息 —— event.option -> Option('Task1')、event.option_index -> 0
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.widgets import OptionList, SelectionList, TextArea
class ToDoApp(App):
BINDINGS = [
Binding("q", "quit", "Quit", show=True),
Binding("n", "new", "New ToDo", show=True),
Binding("d", "delete", "Delete ToDo", show=True),
Binding("j", "down", "Scroll down", show=True),
Binding("k", "up", "Scroll up", show=True),
# doesn't need to bind to `enter`
]
def compose(self) -> ComposeResult:
yield OptionList("Task 1", "Task 2", "Task 3")
yield SelectionList(("Done 1", 1), ("Done 2", 2))
yield TextArea()
def on_option_list_option_selected(self, event: OptionList.OptionSelected) -> None:
"""Executed when you press `Enter` in `OptionList`"""
text_area = self.query_one(TextArea)
text_area.insert(
f"--- selected ---\n{event.option=} | {event.option_index=} | {event.option_id=}\n{event.option_list.options=}\n"
)
if isinstance(self.focused, OptionList):
self.query_one(SelectionList).focus()
if __name__ == "__main__":
ToDoApp().run()
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。
