Skip to content

Commit e4b45ba

Browse files
authored
docs on await mount (#2235)
1 parent c3424b0 commit e4b45ba

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

docs/examples/app/widgets03.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from textual.app import App
2+
from textual.widgets import Button, Welcome
3+
4+
5+
class WelcomeApp(App):
6+
def on_key(self) -> None:
7+
self.mount(Welcome())
8+
self.query_one(Button).label = "YES"
9+
10+
11+
if __name__ == "__main__":
12+
app = WelcomeApp()
13+
app.run()

docs/examples/app/widgets04.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from textual.app import App
2+
from textual.widgets import Button, Welcome
3+
4+
5+
class WelcomeApp(App):
6+
async def on_key(self) -> None:
7+
await self.mount(Welcome())
8+
self.query_one(Button).label = "YES"
9+
10+
11+
if __name__ == "__main__":
12+
app = WelcomeApp()
13+
app.run()

docs/guide/app.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,63 @@ When you first run this you will get a blank screen. Press any key to add the we
117117
```{.textual path="docs/examples/app/widgets02.py" press="a,a,a,down,down,down,down,down,down"}
118118
```
119119

120+
#### Awaiting mount
121+
122+
When you mount a widget, Textual will mount everything the widget *composes*.
123+
Textual guarantees that the mounting will be complete by the *next* message handler, but not immediately after the call to `mount()`.
124+
This may be a problem if you want to make any changes to the widget in the same message handler.
125+
126+
Let's first illustrate the problem with an example.
127+
The following code will mount the Welcome widget in response to a key press.
128+
It will also attempt to modify the Button in the Welcome widget by changing its label from "OK" to "YES".
129+
130+
```python hl_lines="2 8"
131+
from textual.app import App
132+
from textual.widgets import Button, Welcome
133+
134+
135+
class WelcomeApp(App):
136+
def on_key(self) -> None:
137+
self.mount(Welcome())
138+
self.query_one(Button).label = "YES!" # (1)!
139+
140+
141+
if __name__ == "__main__":
142+
app = WelcomeApp()
143+
app.run()
144+
```
145+
146+
1. See [queries](./queries.md) for more information on the `query_one` method.
147+
148+
If you run this example, you will find that Textual raises a [NoMatches][textual.css.query.NoMatches] exception when you press a key.
149+
This is because the mount process has not yet completed when we attempt to change the button.
150+
151+
To solve this we can optionally await the result of `mount()`, which requires we make the function `async`.
152+
This guarantees that by the following line, the Button has been mounted, and we can change its label.
153+
154+
155+
```python hl_lines="6 7"
156+
from textual.app import App
157+
from textual.widgets import Button, Welcome
158+
159+
160+
class WelcomeApp(App):
161+
async def on_key(self) -> None:
162+
await self.mount(Welcome())
163+
self.query_one(Button).label = "YES!"
164+
165+
166+
if __name__ == "__main__":
167+
app = WelcomeApp()
168+
app.run()
169+
```
170+
171+
Here's the output. Note the changed button text:
172+
173+
```{.textual path="docs/examples/app/widgets04.py" press=["a"]}
174+
```
175+
176+
120177
## Exiting
121178

122179
An app will run until you call [App.exit()][textual.app.App.exit] which will exit application mode and the [run][textual.app.App.run] method will return. If this is the last line in your code you will return to the command prompt.

0 commit comments

Comments
 (0)