How can I prevent a button widget from being activated when switching screens with Enter? #2726
-
I have a Textual application with two screens. On the first one, the user is supposed to fill in a few details and press Enter, after which the second screen appears. The problem is that when the user presses Enter on Screen One, the first button widget on Screen Two is unintentionally activated. How can I prevent this from happening? I can reproduce it in both Textual 0.25.0 and 0.27.0. Here is a simplified example: from textual.app import App, ComposeResult
from textual import events
from textual.containers import Vertical
from textual.screen import Screen
from textual.widgets import Button, Static
class MyButton(Button):
pass
class ScreenOne(Screen):
def compose(self) -> ComposeResult:
yield Static("Press Enter to push ScreenTwo.")
def on_key(self, event: events.Key) -> None:
if event.key == "enter":
app.push_screen("two")
class ScreenTwo(Screen):
def compose(self) -> ComposeResult:
yield Vertical(MyButton("Press to hide text below me"), Static("Text 1", classes="text"))
yield Vertical(MyButton("Press to hide text below me"), Static("Text 2", classes="text"))
yield Vertical(MyButton("Press to hide text below me"), Static("Text 3", classes="text"))
yield Vertical(MyButton("Press to hide text below me"), Static("Text 4", classes="text"))
class Vertical(Vertical):
# Initial state
hidden = False
def on_button_pressed(self, event: Button.Pressed) -> None:
"""Actions triggered by pressing the UI buttons."""
if not self.hidden:
self.query(".text").add_class("hidden")
self.hidden = True
else:
self.query(".text").remove_class("hidden")
self.hidden = False
class App(App):
CSS_PATH = "containers.css"
SCREENS = {"one": ScreenOne(), "two": ScreenTwo()}
def on_mount(self) -> None:
app.push_screen("one")
app = App()
app.run() Content of .hidden {
display: none;
}
Vertical {
height: auto;
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Here's a couple of possible solutions: class ScreenOne(Screen):
"""Solution 1: Instead add a Binding to map the key press"""
# BINDINGS = [("enter", "app.push_screen('two')")]
def compose(self) -> ComposeResult:
yield Static("Press Enter to push ScreenTwo.")
def on_key(self, event: events.Key) -> None:
if event.key == "enter":
"""Solution 2: Stop the event from propagating"""
# event.stop()
app.push_screen("two") I think the problem is that the |
Beta Was this translation helpful? Give feedback.
Here's a couple of possible solutions:
I think the problem is that the
on_key
event is never actually processed on your first screen, so the event is passed to your App which then triggers clicking the first button.