mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Merge pull request #1866 from Textualize/prevent-event
Add a "prevent" context manager
This commit is contained in:
26
docs/examples/events/prevent.py
Normal file
26
docs/examples/events/prevent.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.containers import Horizontal
|
||||
from textual.widgets import Button, Input
|
||||
|
||||
|
||||
class PreventApp(App):
|
||||
"""Demonstrates `prevent` context manager."""
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Input()
|
||||
yield Button("Clear", id="clear")
|
||||
|
||||
def on_button_pressed(self) -> None:
|
||||
"""Clear the text input."""
|
||||
input = self.query_one(Input)
|
||||
with input.prevent(Input.Changed): # (1)!
|
||||
input.value = ""
|
||||
|
||||
def on_input_changed(self) -> None:
|
||||
"""Called as the user types."""
|
||||
self.bell() # (2)!
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = PreventApp()
|
||||
app.run()
|
||||
@@ -108,7 +108,7 @@ The message class is defined within the widget class itself. This is not strictl
|
||||
- It creates a namespace for the handler. So rather than `on_selected`, the handler name becomes `on_color_button_selected`. This makes it less likely that your chosen name will clash with another message.
|
||||
|
||||
|
||||
## Sending events
|
||||
## Sending messages
|
||||
|
||||
In the previous example we used [post_message()][textual.message_pump.MessagePump.post_message] to send an event to its parent. We could also have used [post_message_no_wait()][textual.message_pump.MessagePump.post_message_no_wait] for non async code. Sending messages in this way allows you to write custom widgets without needing to know in what context they will be used.
|
||||
|
||||
@@ -118,6 +118,32 @@ There are other ways of sending (posting) messages, which you may need to use le
|
||||
- [post_message_no_wait][textual.message_pump.MessagePump.post_message_no_wait] The non-async version of `post_message`.
|
||||
|
||||
|
||||
## Preventing messages
|
||||
|
||||
You can *temporarily* disable posting of messages of a particular type by calling [prevent][textual.message_pump.MessagePump.prevent], which returns a context manager (used with Python's `with` keyword). This is typically used when updating data in a child widget and you don't want to receive notifications that something has changed.
|
||||
|
||||
The following example will play the terminal bell as you type. It does this by handling [Input.Changed][textual.widgets.Input.Changed] and calling [bell()][textual.app.App.bell]. There is a Clear button which sets the input's value to an empty string. This would normally also result in a `Input.Changed` event being sent (and the bell playing). Since we don't want the button to make a sound, the assignment to `value` is wrapped within a [prevent][textual.message_pump.MessagePump.prevent] context manager.
|
||||
|
||||
!!! tip
|
||||
|
||||
In reality, playing the terminal bell as you type would be very irritating -- we don't recommend it!
|
||||
|
||||
=== "prevent.py"
|
||||
|
||||
```python title="prevent.py"
|
||||
--8<-- "docs/examples/events/prevent.py"
|
||||
```
|
||||
|
||||
1. Clear the input without sending an Input.Changed event.
|
||||
2. Plays the terminal sound when typing.
|
||||
|
||||
=== "Output"
|
||||
|
||||
```{.textual path="docs/examples/events/prevent.py"}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Message handlers
|
||||
|
||||
Most of the logic in a Textual app will be written in message handlers. Let's explore handlers in more detail.
|
||||
|
||||
Reference in New Issue
Block a user