mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
@@ -1,9 +1,9 @@
|
||||
from random import randint
|
||||
import time
|
||||
from random import randint
|
||||
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.color import Color
|
||||
from textual.containers import Grid, Vertical
|
||||
from textual.containers import Grid, VerticalScroll
|
||||
from textual.widget import Widget
|
||||
from textual.widgets import Footer, Label
|
||||
|
||||
@@ -28,7 +28,7 @@ class MyApp(App[None]):
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Grid(
|
||||
ColourChanger(),
|
||||
Vertical(id="log"),
|
||||
VerticalScroll(id="log"),
|
||||
)
|
||||
yield Footer()
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import asyncio
|
||||
from random import randint
|
||||
import time
|
||||
from random import randint
|
||||
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.color import Color
|
||||
from textual.containers import Grid, Vertical
|
||||
from textual.containers import Grid, VerticalScroll
|
||||
from textual.widget import Widget
|
||||
from textual.widgets import Footer, Label
|
||||
|
||||
@@ -29,7 +29,7 @@ class MyApp(App[None]):
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Grid(
|
||||
ColourChanger(),
|
||||
Vertical(id="log"),
|
||||
VerticalScroll(id="log"),
|
||||
)
|
||||
yield Footer()
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import asyncio
|
||||
from random import randint
|
||||
import time
|
||||
from random import randint
|
||||
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.color import Color
|
||||
from textual.containers import Grid, Vertical
|
||||
from textual.containers import Grid, VerticalScroll
|
||||
from textual.widget import Widget
|
||||
from textual.widgets import Footer, Label
|
||||
|
||||
@@ -29,7 +29,7 @@ class MyApp(App[None]):
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Grid(
|
||||
ColourChanger(),
|
||||
Vertical(id="log"),
|
||||
VerticalScroll(id="log"),
|
||||
)
|
||||
yield Footer()
|
||||
|
||||
|
||||
@@ -6,9 +6,10 @@ except ImportError:
|
||||
raise ImportError("Please install httpx with 'pip install httpx' ")
|
||||
|
||||
from rich.json import JSON
|
||||
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.containers import Vertical
|
||||
from textual.widgets import Static, Input
|
||||
from textual.containers import VerticalScroll
|
||||
from textual.widgets import Input, Static
|
||||
|
||||
|
||||
class DictionaryApp(App):
|
||||
@@ -18,7 +19,7 @@ class DictionaryApp(App):
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Input(placeholder="Search for a word")
|
||||
yield Vertical(Static(id="results"), id="results-container")
|
||||
yield VerticalScroll(Static(id="results"), id="results-container")
|
||||
|
||||
async def on_input_changed(self, message: Input.Changed) -> None:
|
||||
"""A coroutine to handle a text changed message."""
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.containers import Container, Horizontal, Vertical
|
||||
from textual.containers import Container, Horizontal, VerticalScroll
|
||||
from textual.widgets import Header, Static
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ class CombiningLayoutsExample(App):
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Header()
|
||||
with Container(id="app-grid"):
|
||||
with Vertical(id="left-pane"):
|
||||
with VerticalScroll(id="left-pane"):
|
||||
for number in range(15):
|
||||
yield Static(f"Vertical layout, child {number}")
|
||||
with Horizontal(id="top-right"):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.containers import Horizontal, Vertical
|
||||
from textual.containers import Horizontal, VerticalScroll
|
||||
from textual.widgets import Static
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@ class UtilityContainersExample(App):
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Horizontal(
|
||||
Vertical(
|
||||
VerticalScroll(
|
||||
Static("One"),
|
||||
Static("Two"),
|
||||
classes="column",
|
||||
),
|
||||
Vertical(
|
||||
VerticalScroll(
|
||||
Static("Three"),
|
||||
Static("Four"),
|
||||
classes="column",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.containers import Horizontal, Vertical
|
||||
from textual.containers import Horizontal, VerticalScroll
|
||||
from textual.widgets import Static
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@ class UtilityContainersExample(App):
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
with Horizontal():
|
||||
with Vertical(classes="column"):
|
||||
with VerticalScroll(classes="column"):
|
||||
yield Static("One")
|
||||
yield Static("Two")
|
||||
with Vertical(classes="column"):
|
||||
with VerticalScroll(classes="column"):
|
||||
yield Static("Three")
|
||||
yield Static("Four")
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from textual.app import App
|
||||
from textual.containers import Vertical
|
||||
from textual.widgets import Placeholder, Label, Static
|
||||
from textual.containers import VerticalScroll
|
||||
from textual.widgets import Label, Placeholder, Static
|
||||
|
||||
|
||||
class Ruler(Static):
|
||||
@@ -11,7 +11,7 @@ class Ruler(Static):
|
||||
|
||||
class HeightComparisonApp(App):
|
||||
def compose(self):
|
||||
yield Vertical(
|
||||
yield VerticalScroll(
|
||||
Placeholder(id="cells"), # (1)!
|
||||
Placeholder(id="percent"),
|
||||
Placeholder(id="w"),
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from textual.app import App
|
||||
from textual.containers import Vertical
|
||||
from textual.containers import VerticalScroll
|
||||
from textual.widgets import Placeholder
|
||||
|
||||
|
||||
class MaxWidthApp(App):
|
||||
def compose(self):
|
||||
yield Vertical(
|
||||
yield VerticalScroll(
|
||||
Placeholder("max-width: 50h", id="p1"),
|
||||
Placeholder("max-width: 999", id="p2"),
|
||||
Placeholder("max-width: 50%", id="p3"),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Vertical {
|
||||
VerticalScroll {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
@@ -10,7 +10,8 @@ Placeholder {
|
||||
}
|
||||
|
||||
#p1 {
|
||||
min-width: 25%; /* (1)! */
|
||||
min-width: 25%;
|
||||
/* (1)! */
|
||||
}
|
||||
|
||||
#p2 {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from textual.app import App
|
||||
from textual.containers import Vertical
|
||||
from textual.containers import VerticalScroll
|
||||
from textual.widgets import Placeholder
|
||||
|
||||
|
||||
class MinWidthApp(App):
|
||||
def compose(self):
|
||||
yield Vertical(
|
||||
yield VerticalScroll(
|
||||
Placeholder("min-width: 25%", id="p1"),
|
||||
Placeholder("min-width: 75%", id="p2"),
|
||||
Placeholder("min-width: 100", id="p3"),
|
||||
|
||||
@@ -3,7 +3,7 @@ Screen {
|
||||
color: black;
|
||||
}
|
||||
|
||||
Vertical {
|
||||
VerticalScroll {
|
||||
width: 1fr;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ Static {
|
||||
border: green wide;
|
||||
color: white 90%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
#right {
|
||||
overflow-y: hidden;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from textual.app import App
|
||||
from textual.containers import Horizontal, VerticalScroll
|
||||
from textual.widgets import Static
|
||||
from textual.containers import Horizontal, Vertical
|
||||
|
||||
TEXT = """I must not fear.
|
||||
Fear is the mind-killer.
|
||||
@@ -14,8 +14,8 @@ Where the fear has gone there will be nothing. Only I will remain."""
|
||||
class OverflowApp(App):
|
||||
def compose(self):
|
||||
yield Horizontal(
|
||||
Vertical(Static(TEXT), Static(TEXT), Static(TEXT), id="left"),
|
||||
Vertical(Static(TEXT), Static(TEXT), Static(TEXT), id="right"),
|
||||
VerticalScroll(Static(TEXT), Static(TEXT), Static(TEXT), id="left"),
|
||||
VerticalScroll(Static(TEXT), Static(TEXT), Static(TEXT), id="right"),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from textual.app import App
|
||||
from textual.containers import Vertical
|
||||
from textual.containers import VerticalScroll
|
||||
from textual.widgets import Label
|
||||
|
||||
TEXT = """I must not fear.
|
||||
@@ -14,7 +14,7 @@ Where the fear has gone there will be nothing. Only I will remain.
|
||||
|
||||
class ScrollbarApp(App):
|
||||
def compose(self):
|
||||
yield Vertical(Label(TEXT * 5), classes="panel")
|
||||
yield VerticalScroll(Label(TEXT * 5), classes="panel")
|
||||
|
||||
|
||||
app = ScrollbarApp(css_path="scrollbar_size.css")
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from textual.app import App
|
||||
from textual.containers import Horizontal, Vertical
|
||||
from textual.containers import Horizontal, VerticalScroll
|
||||
from textual.widgets import Placeholder
|
||||
|
||||
|
||||
class VisibilityContainersApp(App):
|
||||
def compose(self):
|
||||
yield Vertical(
|
||||
yield VerticalScroll(
|
||||
Horizontal(
|
||||
Placeholder(),
|
||||
Placeholder(),
|
||||
|
||||
@@ -2,7 +2,7 @@ Button {
|
||||
margin: 1 2;
|
||||
}
|
||||
|
||||
Horizontal > Vertical {
|
||||
Horizontal>VerticalScroll {
|
||||
width: 24;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.containers import Horizontal, Vertical
|
||||
from textual.containers import Horizontal, VerticalScroll
|
||||
from textual.widgets import Button, Static
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ class ButtonsApp(App[str]):
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Horizontal(
|
||||
Vertical(
|
||||
VerticalScroll(
|
||||
Static("Standard Buttons", classes="header"),
|
||||
Button("Default"),
|
||||
Button("Primary!", variant="primary"),
|
||||
@@ -16,7 +16,7 @@ class ButtonsApp(App[str]):
|
||||
Button.warning("Warning!"),
|
||||
Button.error("Error!"),
|
||||
),
|
||||
Vertical(
|
||||
VerticalScroll(
|
||||
Static("Disabled Buttons", classes="header"),
|
||||
Button("Default", disabled=True),
|
||||
Button("Primary!", variant="primary", disabled=True),
|
||||
|
||||
@@ -2,7 +2,7 @@ Screen {
|
||||
align: center middle;
|
||||
}
|
||||
|
||||
Vertical {
|
||||
VerticalScroll {
|
||||
width: auto;
|
||||
height: auto;
|
||||
border: solid $primary;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.containers import Vertical
|
||||
from textual.containers import VerticalScroll
|
||||
from textual.widgets import Checkbox
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ class CheckboxApp(App[None]):
|
||||
CSS_PATH = "checkbox.css"
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
with Vertical():
|
||||
with VerticalScroll():
|
||||
yield Checkbox("Arrakis :sweat:")
|
||||
yield Checkbox("Caladan")
|
||||
yield Checkbox("Chusuk")
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.containers import Container, Horizontal, Vertical
|
||||
from textual.containers import Container, Horizontal, VerticalScroll
|
||||
from textual.widgets import Placeholder
|
||||
|
||||
|
||||
class PlaceholderApp(App):
|
||||
|
||||
CSS_PATH = "placeholder.css"
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Vertical(
|
||||
yield VerticalScroll(
|
||||
Container(
|
||||
Placeholder("This is a custom label for p1.", id="p1"),
|
||||
Placeholder("Placeholder p2 here!", id="p2"),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Vertical {
|
||||
VerticalScroll {
|
||||
align: center middle;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.containers import Horizontal, Vertical
|
||||
from textual.containers import Horizontal, VerticalScroll
|
||||
from textual.widgets import Label, RadioButton, RadioSet
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ class RadioSetChangedApp(App[None]):
|
||||
CSS_PATH = "radio_set_changed.css"
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
with Vertical():
|
||||
with VerticalScroll():
|
||||
with Horizontal():
|
||||
with RadioSet():
|
||||
yield RadioButton("Battlestar Galactica")
|
||||
|
||||
@@ -135,10 +135,10 @@ exceeds the available horizontal space in the parent container.
|
||||
## Utility containers
|
||||
|
||||
Textual comes with several "container" widgets.
|
||||
These are [Vertical][textual.containers.Vertical], [Horizontal][textual.containers.Horizontal], and [Grid][textual.containers.Grid] which have the corresponding layout.
|
||||
These are [VerticalScroll][textual.containers.VerticalScroll], [Horizontal][textual.containers.Horizontal], and [Grid][textual.containers.Grid] which have the corresponding layout.
|
||||
|
||||
The example below shows how we can combine these containers to create a simple 2x2 grid.
|
||||
Inside a single `Horizontal` container, we place two `Vertical` containers.
|
||||
Inside a single `Horizontal` container, we place two `VerticalScroll` containers.
|
||||
In other words, we have a single row containing two columns.
|
||||
|
||||
=== "Output"
|
||||
@@ -163,7 +163,7 @@ However, Textual comes with a more powerful mechanism for achieving this known a
|
||||
|
||||
## Composing with context managers
|
||||
|
||||
In the previous section we've show how you add children to a container (such as `Horizontal` and `Vertical`) using positional arguments.
|
||||
In the previous section we've show how you add children to a container (such as `Horizontal` and `VerticalScroll`) using positional arguments.
|
||||
It's fine to do it this way, but Textual offers a simplified syntax using [context managers](https://docs.python.org/3/reference/datamodel.html#context-managers) which is generally easier to write and edit.
|
||||
|
||||
When composing a widget, you can introduce a container using Python's `with` statement.
|
||||
|
||||
@@ -61,8 +61,8 @@ Open the CSS file tab to see the comments that explain how each height is comput
|
||||
|
||||
1. This sets the height to 2 lines.
|
||||
2. This sets the height to 12.5% of the space made available by the container. The container is 24 lines tall, so 12.5% of 24 is 3.
|
||||
3. This sets the height to 5% of the width of the direct container, which is the `Vertical` container. Because it expands to fit all of the terminal, the width of the `Vertical` is 80 and 5% of 80 is 4.
|
||||
4. This sets the height to 12.5% of the height of the direct container, which is the `Vertical` container. Because it expands to fit all of the terminal, the height of the `Vertical` is 24 and 12.5% of 24 is 3.
|
||||
3. This sets the height to 5% of the width of the direct container, which is the `VerticalScroll` container. Because it expands to fit all of the terminal, the width of the `VerticalScroll` is 80 and 5% of 80 is 4.
|
||||
4. This sets the height to 12.5% of the height of the direct container, which is the `VerticalScroll` container. Because it expands to fit all of the terminal, the height of the `VerticalScroll` is 24 and 12.5% of 24 is 3.
|
||||
5. This sets the height to 6.25% of the viewport width, which is 80. 6.25% of 80 is 5.
|
||||
6. This sets the height to 12.5% of the viewport height, which is 24. 12.5% of 24 is 3.
|
||||
7. This sets the height of the placeholder to be the optimal size that fits the content without scrolling.
|
||||
|
||||
@@ -25,7 +25,7 @@ The default setting for containers is `overflow: auto auto`.
|
||||
|
||||
!!! warning
|
||||
|
||||
Some built-in containers like `Horizontal` and `Vertical` override these defaults.
|
||||
Some built-in containers like `Horizontal` and `VerticalScroll` override these defaults.
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
Reference in New Issue
Block a user