mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
renamed introduction to tutorial
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# App Basics
|
||||
|
||||
In this chapter we will cover what you will need to know to build a Textual application. Just enough to get you up to speed. We will go in to more detail in the following chapters.
|
||||
In this chapter we will cover how to use Textual's App class to create an application. Just enough to get you up to speed. We will go in to more detail in the following chapters.
|
||||
|
||||
## The App class
|
||||
|
||||
@@ -26,20 +26,24 @@ Apps don't get much simpler than this—don't expect it to do much.
|
||||
|
||||
If we run this app with `python simple02.py` you will see a blank terminal, something like the following:
|
||||
|
||||
```{.textual path="docs/examples/app/simple02.py" title="simple02.py"}
|
||||
```{.textual path="docs/examples/app/simple02.py"}
|
||||
```
|
||||
|
||||
When you call [App.run()][textual.app.App.run] Textual puts the terminal in to a special state called *application mode*. When in application mode, the terminal will no longer echo what you type. Textual will take over responding to user input (keyboard and mouse) and will update the visible portion of the terminal (i.e. the *screen*).
|
||||
When you call [App.run()][textual.app.App.run] Textual puts the terminal in to a special state called *application mode*. When in application mode the terminal will no longer echo what you type. Textual will take over responding to user input (keyboard and mouse) and will update the visible portion of the terminal (i.e. the *screen*).
|
||||
|
||||
If you hit ++ctrl+c++ Textual will exit application mode and return you to the command prompt. Any content you had in the terminal prior to application mode will be restored.
|
||||
|
||||
## Events
|
||||
|
||||
Textual has an event system you can use to respond to key presses, mouse actions, and also internal state changes. Event handlers are methods which are prefixed with `on_` followed by the name of the event.
|
||||
Textual has an event system you can use to respond to key presses, mouse actions, and internal state changes. Event handlers are methods which are prefixed with `on_` followed by the name of the event.
|
||||
|
||||
One such event is the *mount* event which is sent to an application after it enters application mode. You can respond to this event by defining a method called `on_mount`.
|
||||
|
||||
Another such event is `on_key` which is sent when the user presses a key. The following example contains handlers for both those events:
|
||||
!!! info
|
||||
|
||||
You may have noticed we use the term "send" and "sent" in relation to event handler methods in preference to "calling". This is because Textual uses a message passing system where events are passed (or *sent*) between components. We will cover the details in [events][events.md].
|
||||
|
||||
Another such event is the *key* event which is sent when the user presses a key. The following example contains handlers for both those events:
|
||||
|
||||
```python title="event01.py"
|
||||
--8<-- "docs/examples/app/event01.py"
|
||||
@@ -50,21 +54,21 @@ The `on_mount` handler sets the `self.styles.background` attribute to `"darkblue
|
||||
```{.textual path="docs/examples/app/event01.py" hl_lines="23-25"}
|
||||
```
|
||||
|
||||
The key event handler (`on_key`) specifies an `event` parameter which should be a [events.Key][textual.events.Key] instance. Every event has an associated event object which will be passed to the handler method if it is present in the method's parameter list.
|
||||
The key event handler (`on_key`) specifies an `event` parameter which will receive a [events.Key][textual.events.Key] instance. Every event has an associated event object which will be passed to the handler method if it is present in the method's parameter list.
|
||||
|
||||
!!! note
|
||||
|
||||
It is unusual for a method's parameters to affect how it is called. Textual accomplishes this by inspecting the method prior to calling it.
|
||||
It is unusual (but not unprecedented) for a method's parameters to affect how it is called. Textual accomplishes this by inspecting the method prior to calling it.
|
||||
|
||||
For some events, such as the key event, there is additional information on the event object. In the case of [events.Key][textual.events.Key] it will contain the key that was pressed.
|
||||
For some events, such as the key event, the event object contains additional information. In the case of [events.Key][textual.events.Key] it will contain the key that was pressed.
|
||||
|
||||
The `on_key` method above uses the `key` attribute on the Key event to change the background color if any of the keys 0-9 are pressed.
|
||||
The `on_key` method above uses the `key` attribute on the Key event to change the background color if any of the keys ++0++ to ++9++ are pressed.
|
||||
|
||||
### Async events
|
||||
|
||||
Textual is powered by Python's [asyncio](https://docs.python.org/3/library/asyncio.html) framework which uses the `async` and `await` keywords to coordinate events.
|
||||
|
||||
Textual knows to *await* your event handlers if they are generators (i.e. prefixed with the `async` keywords).
|
||||
Textual knows to *await* your event handlers if they are generators (i.e. prefixed with the `async` keyword).
|
||||
|
||||
!!! note
|
||||
|
||||
@@ -88,10 +92,10 @@ The following example imports a builtin Welcome widget and yields it from compos
|
||||
|
||||
When you run this code, Textual will *mount* the Welcome widget which contains a Markdown content area and a button:
|
||||
|
||||
```{.textual path="docs/examples/app/widgets01.py" title="widgets01.py" }
|
||||
```{.textual path="docs/examples/app/widgets01.py"}
|
||||
```
|
||||
|
||||
Notice the `on_button_pressed` method which handles the [Button.Pressed][textual.widgets.Button] event send by the button contained in the Welcome widget. The handlers calls [App.exit()][textual.app.App] to exit the app.
|
||||
Notice the `on_button_pressed` method which handles the [Button.Pressed][textual.widgets.Button] event sent by a button contained in the Welcome widget. The handler calls [App.exit()][textual.app.App] to exit the app.
|
||||
|
||||
### Mounting
|
||||
|
||||
@@ -105,7 +109,7 @@ Here's an app which adds the welcome widget in response to any key press:
|
||||
|
||||
When you first run this you will get a blank screen. Press any key to add the welcome widget. You can even press a key multiple times to add several widgets.
|
||||
|
||||
```{.textual path="docs/examples/app/widgets02.py" title="widgets02.py" press="a,a,a,down,down,down,down,down,down,_,_,_,_,_,_"}
|
||||
```{.textual path="docs/examples/app/widgets02.py" press="a,a,a,down,down,down,down,down,down,_,_,_,_,_,_"}
|
||||
```
|
||||
|
||||
### Exiting
|
||||
@@ -138,3 +142,36 @@ The addition of `[str]` tells Mypy that `run()` is expected to return a string.
|
||||
!!! note
|
||||
|
||||
Type annotations are entirely optional (but recommended) with Textual.
|
||||
|
||||
## CSS
|
||||
|
||||
Textual apps can reference [CSS](CSS.md) files which define how your app and widgets will look, while keeping your Python code free of display related code (which tends to be messy).
|
||||
|
||||
The following chapter on [Textual CSS](CSS.md) will describe how to use CSS in detail. For now lets look at how your app references external CSS files.
|
||||
|
||||
The following example sets the `css_path` attribute on the app:
|
||||
|
||||
```python title="question02.py" hl_lines="15"
|
||||
--8<-- "docs/examples/app/question02.py"
|
||||
```
|
||||
|
||||
If the path is relative (as it is above) then it is taken as relative to where the app is defined. Hence this example references `"question01.css"` in the same directory as the Python code. Here is that CSS file:
|
||||
|
||||
```sass title="question02.css"
|
||||
--8<-- "docs/examples/app/question02.css"
|
||||
```
|
||||
|
||||
When `"question02.py"` runs it will load `"question02.css"` and update the app and widgets accordingly. Even though the code is almost identical to the previous sample, the app now looks quite different:
|
||||
|
||||
```{.textual path="docs/examples/app/question02.py"}
|
||||
```
|
||||
|
||||
### Classvar CSS
|
||||
|
||||
While external CSS files are recommended for most applications, and enable some cool features like *live editing* (see below), you can also specify the CSS directly within the Python code. To do this you can set the `CSS` class variable on the app which contains the CSS content.
|
||||
|
||||
Here's the question app with classvar CSS:
|
||||
|
||||
```python title="question03.py" hl_lines="6-24"
|
||||
--8<-- "docs/examples/app/question03.py"
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user