mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
console screenshot
This commit is contained in:
18
docs/examples/getting_started/console.py
Normal file
18
docs/examples/getting_started/console.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
"""
|
||||||
|
Simulates a screenshot of the Textual devtools
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from textual.app import App
|
||||||
|
|
||||||
|
from textual.devtools.renderables import DevConsoleHeader
|
||||||
|
from textual.widgets import Static
|
||||||
|
|
||||||
|
|
||||||
|
class ConsoleApp(App):
|
||||||
|
def compose(self):
|
||||||
|
self.dark = True
|
||||||
|
yield Static(DevConsoleHeader())
|
||||||
|
|
||||||
|
|
||||||
|
app = ConsoleApp()
|
||||||
@@ -18,9 +18,6 @@ pip install textual
|
|||||||
|
|
||||||
If you installed the dev dependencies, you have have access to the `textual` CLI command. There are a number of sub-commands which will aid you in building Textual apps. See the help for more details:
|
If you installed the dev dependencies, you have have access to the `textual` CLI command. There are a number of sub-commands which will aid you in building Textual apps. See the help for more details:
|
||||||
|
|
||||||
```python
|
```bash
|
||||||
textual --help
|
textual --help
|
||||||
```
|
```
|
||||||
|
|
||||||
### Textual Console
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,20 +28,24 @@ textual run my_app.py:alternative_app
|
|||||||
|
|
||||||
## Console
|
## Console
|
||||||
|
|
||||||
When running any terminal application, you can no longer use `print` when debugging (or log to the console). This is because anything you write to standard output would typically overwrite application content, which generally makes an unreadable mess. Fortunately Textual supplies a debug console of it's own which has some super helpful features.
|
When running any terminal application, you can no longer use `print` when debugging (or log to the console). This is because anything you write to standard output would overwrite application content, making it unreadable. Fortunately Textual supplies a debug console of it's own which has some super helpful features.
|
||||||
|
|
||||||
To use the console, open up 2 console emulators. In the first one, run the following:
|
To use the console, open up 2 terminal emulators. In the first one, run the following:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
textual console
|
textual console
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This should look something like the following:
|
||||||
|
|
||||||
|
```{.textual title="textual console" path="docs/examples/getting_started/console.py", press="_,_"}
|
||||||
|
```
|
||||||
|
|
||||||
In the other console, run your application using `textual run` and the `--dev` switch:
|
In the other console, run your application using `textual run` and the `--dev` switch:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
textual run my_app.py --dev
|
textual run my_app.py --dev
|
||||||
```
|
```
|
||||||
|
|
||||||
You should notice that the console will display information regarding the running application, such as events which are sent.
|
|
||||||
|
|
||||||
Anything you `print` from your application will be displayed in the console window. You can also call the `log()` method on App and Widget objects for advanced formatting. Try it with `self.log(self.tree)`.
|
Anything you `print` from your application will be displayed in the console window. You can also call the `log()` method on App and Widget objects for advanced formatting. Try it with `self.log(self.tree)`.
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ By the end of this page you should have a good idea of the steps involved in cre
|
|||||||
|
|
||||||
## Stopwatch Application
|
## Stopwatch Application
|
||||||
|
|
||||||
We're going to build a stopwatch app. This app will display the elapsed time since the user hit a "Start" button. The user will be able to stop, resume, and reset each stopwatch in addition to adding or removing them.
|
We're going to build a stopwatch application. It should show a list of stopwatches with a time display the user can start, stop, and reset. We also want the user to be able to add and remove stopwatches as required.
|
||||||
|
|
||||||
This will be a simple yet **fully featured** app — you could distribute this app if you wanted to!
|
This will be a simple yet **fully featured** app — you could distribute this app if you wanted to!
|
||||||
|
|
||||||
|
|||||||
@@ -463,7 +463,6 @@ class Compositor:
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
raise errors.NoWidget("Widget is not in layout")
|
raise errors.NoWidget("Widget is not in layout")
|
||||||
|
|
||||||
@timer("get_widget_at")
|
|
||||||
def get_widget_at(self, x: int, y: int) -> tuple[Widget, Region]:
|
def get_widget_at(self, x: int, y: int) -> tuple[Widget, Region]:
|
||||||
"""Get the widget under the given point or None."""
|
"""Get the widget under the given point or None."""
|
||||||
# TODO: Optimize with some line based lookup
|
# TODO: Optimize with some line based lookup
|
||||||
|
|||||||
@@ -20,7 +20,15 @@ def run():
|
|||||||
|
|
||||||
@run.command(help="Run the Textual Devtools console.")
|
@run.command(help="Run the Textual Devtools console.")
|
||||||
def console():
|
def console():
|
||||||
|
from rich.console import Console
|
||||||
|
|
||||||
|
console = Console()
|
||||||
|
console.clear()
|
||||||
|
console.show_cursor(False)
|
||||||
|
try:
|
||||||
_run_devtools()
|
_run_devtools()
|
||||||
|
finally:
|
||||||
|
console.show_cursor(True)
|
||||||
|
|
||||||
|
|
||||||
class AppFail(Exception):
|
class AppFail(Exception):
|
||||||
|
|||||||
@@ -6,22 +6,22 @@ from pathlib import Path
|
|||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
|
||||||
from importlib_metadata import version
|
from importlib_metadata import version
|
||||||
from rich.containers import Renderables
|
|
||||||
from rich.style import Style
|
|
||||||
from rich.text import Text
|
|
||||||
|
|
||||||
if sys.version_info >= (3, 8):
|
if sys.version_info >= (3, 8):
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
else:
|
else:
|
||||||
from typing_extensions import Literal
|
from typing_extensions import Literal
|
||||||
|
|
||||||
from rich.console import Console
|
|
||||||
from rich.align import Align
|
from rich.align import Align
|
||||||
from rich.console import ConsoleOptions, RenderResult
|
from rich.console import Console, ConsoleOptions, RenderResult
|
||||||
from rich.markup import escape
|
from rich.markup import escape
|
||||||
from rich.rule import Rule
|
from rich.rule import Rule
|
||||||
from rich.segment import Segment, Segments
|
from rich.segment import Segment, Segments
|
||||||
|
from rich.style import Style
|
||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
|
from rich.text import Text
|
||||||
|
|
||||||
|
from textual._border import Border
|
||||||
|
|
||||||
DevConsoleMessageLevel = Literal["info", "warning", "error"]
|
DevConsoleMessageLevel = Literal["info", "warning", "error"]
|
||||||
|
|
||||||
@@ -30,17 +30,17 @@ class DevConsoleHeader:
|
|||||||
def __rich_console__(
|
def __rich_console__(
|
||||||
self, console: Console, options: ConsoleOptions
|
self, console: Console, options: ConsoleOptions
|
||||||
) -> RenderResult:
|
) -> RenderResult:
|
||||||
lines = Renderables(
|
preamble = Text.from_markup(
|
||||||
[
|
f"[bold]Textual Development Console [magenta]v{version('textual')}\n"
|
||||||
f"[bold]Textual Development Console [magenta]v{version('textual')}",
|
"[magenta]Run a Textual app with [reverse]textual run --dev my_app.py[/] to connect.\n"
|
||||||
"[magenta]Run a Textual app with the environment variable [b]TEXTUAL=devtools[/] to connect.",
|
"[magenta]Press [reverse]Ctrl+C[/] to quit."
|
||||||
"[magenta]Press [b]Ctrl+C[/] to quit.",
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
render_options = options.update(width=options.max_width - 4)
|
render_options = options.update(width=options.max_width - 4)
|
||||||
lines = console.render_lines(lines, render_options)
|
lines = console.render_lines(preamble, render_options)
|
||||||
new_line = Segment("\n")
|
|
||||||
|
new_line = Segment.line()
|
||||||
padding = Segment("▌", Style.parse("bright_magenta"))
|
padding = Segment("▌", Style.parse("bright_magenta"))
|
||||||
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
yield padding
|
yield padding
|
||||||
yield from line
|
yield from line
|
||||||
|
|||||||
Reference in New Issue
Block a user