Bindings not working if custom ListView
is empty?
#2262
-
I'm not sure if this is actually expected behaviour and I'm just doing this wrong, so asking here in the discussions rather than raising an issue! I've created a minimal reproduction below - the basic idea is that the user will add new items to the list via the input. The problem I've found is that when the list is empty, the binding to focus the input doesn't work. If you uncomment the Any help as always is much appreciated! from textual.app import App, ComposeResult
from textual.containers import Container
from textual.widgets import Button, Footer, Input, Label, ListItem, ListView
class CustomListView(ListView):
BINDINGS = [("i", "focus_input", "Input")]
def action_focus_input(self) -> None:
self.app.query_one("Input").focus()
class EmptyListApp(App):
CSS = """
Screen {
align: center middle;
}
#sidebar {
dock: right;
width: 40%;
height: 100%;
}
CustomListView {
height: 90%;
}
CustomListView:focus {
border: round $accent;
}
"""
BINDINGS = [("l", "focus_list", "Focus List")]
def compose(self) -> ComposeResult:
with Container(id="sidebar"):
yield Input(placeholder="Enter a new item...")
yield CustomListView(
# ListItem(
# Label("Test item"),
# )
)
yield Button("Widget with initial focus")
yield Footer()
def on_mount(self) -> None:
self.query_one("Button").focus()
def action_focus_list(self) -> None:
self.query_one("CustomListView").focus()
def on_input_submitted(self, event: Input.Submitted) -> None:
# ---snip---
... |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Can confirm what you're seeing, and as best as I can tell after a very quick test, it might be down to some logic somewhere treating a node as a boolean value. Compare this code: from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.containers import Vertical
from textual.widgets import Header, Footer, ListView, Input
class MyListView(ListView):
BINDINGS = [
Binding( "i", "input", "Focus Input" ),
]
def action_input(self) -> None:
self.app.bell()
self.app.query_one( Input ).focus()
class LVFocusApp( App[ None ] ):
CSS = """
MyListView {
height: 1fr;
border: solid blue;
}
MyListView:focus {
border: double green;
}
"""
def compose( self ) -> ComposeResult:
yield Header()
with Vertical():
yield Input()
yield MyListView()
yield Footer()
if __name__ == "__main__":
LVFocusApp().run() which exhibits the issue you're seeing, with this code: from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.containers import Vertical
from textual.widgets import Header, Footer, ListView, Input
class MyListView(ListView):
BINDINGS = [
Binding( "i", "input", "Focus Input" ),
]
def action_input(self) -> None:
self.app.bell()
self.app.query_one( Input ).focus()
def __len__(self):
return 1
class LVFocusApp( App[ None ] ):
CSS = """
MyListView {
height: 1fr;
border: solid blue;
}
MyListView:focus {
border: double green;
}
"""
def compose( self ) -> ComposeResult:
yield Header()
with Vertical():
yield Input()
yield MyListView()
yield Footer()
if __name__ == "__main__":
LVFocusApp().run()
@darrenburns saw something similar to this around if app.screen.focused:
... when it should have been: if app.screen.focused is not None:
... or similar. I'd say this is issue-worthy. |
Beta Was this translation helpful? Give feedback.
Can confirm what you're seeing, and as best as I can tell after a very quick test, it might be down to some logic somewhere treating a node as a boolean value. Compare this code: