我正在尝试创建一个 enditor,其中页脚包含左侧的常用绑定和右侧的一些状态信息,例如行号。 文本中的页脚非常简单,所以我想扩展它,但我无法看到我的标签和基本页脚的绑定。 这是我的代码:
class MyFooter(Footer):
DEFAULT_CSS = """
MyFooter {
.right-label {
text-align: right;
}
}
"""
def compose(self) -> ComposeResult:
for widget in super().compose():
yield widget
yield Label("This is the right side label", id="right-label")
要测试它,您可以使用本教程的第一个示例:
from textual.app import App, ComposeResult
from textual.widgets import Header, Footer,Label
class MyFooter(Footer):
DEFAULT_CSS = """
MyFooter {
.right-label {
text-align: right;
}
}
"""
def compose(self) -> ComposeResult:
"""Create child widgets for the footer."""
for widget in super().compose():
yield widget
yield Label("This is the right side label", id="right-label")
class StopwatchApp(App):
"""A Textual app to manage stopwatches."""
BINDINGS = [("d", "toggle_dark", "Toggle dark mode")]
def compose(self) -> ComposeResult:
"""Create child widgets for the app."""
yield Header()
yield MyFooter()
def action_toggle_dark(self) -> None:
"""An action to toggle dark mode."""
self.dark = not self.dark
if __name__ == "__main__":
app = StopwatchApp()
app.run()
from textual.app import App, ComposeResult
from textual.widgets import Footer, Label, TextLog
from textual.reactive import Reactive
class MyFooter(Footer):
DEFAULT_CSS = """
MyFooter {
dock: bottom;
width: 100%;
background: $panel;
color: $text;
height: 1;
}
.left-label {
dock: left;
}
.right-label {
dock: right;
}
"""
def __init__(self) -> None:
super().__init__()
self.left_label = Label("Left Side", id="left-label")
self.right_label = Label("Right Side", id="right-label")
def compose(self) -> ComposeResult:
yield self.left_label
yield self.right_label
class StopwatchApp(App):
"""A Textual app to manage stopwatches."""
BINDINGS = [("d", "toggle_dark", "Toggle dark mode")]
current_line = Reactive(1)
def compose(self) -> ComposeResult:
"""Create child widgets for the app."""
yield TextLog(id="log")
yield MyFooter()
def action_toggle_dark(self) -> None:
"""An action to toggle dark mode."""
self.dark = not self.dark
def on_mount(self):
self.query_one(TextLog).focus()
def on_key(self, event):
if event.key == "enter":
self.current_line += 1
self.query_one("#right-label", Label).update(f"Line {self.current_line}")
if __name__ == "__main__":
app = StopwatchApp()
app.run()
Here's a breakdown of the code:
- Import Necessary Modules:
-
App
,ComposeResult
,Footer
,Label
, andTextLog
are imported fromtextual
for creating the app, composing widgets, and handling user input. -
Reactive
is imported fromtextual.reactive
to create reactive variables. -
Create the Footer:
-
A custom footer class
MyFooter
is defined, inheriting fromtextual.widgets.Footer
. - It sets up the layout with CSS to place labels on the left and right sides.
-
It uses
Label
widgets for both sides and defines their initial content. -
The
compose
method yields these labels, making them part of the footer. -
Create the Application:
-
StopwatchApp
inherits fromtextual.app.App
. -
It defines a key binding to toggle dark mode with
d
. -
A reactive variable
current_line
is introduced to keep track of the current line number, starting at 1. -
The
compose
method creates and yields aTextLog
for the main content and the customMyFooter
. -
The
on_mount
method sets the initial focus to theTextLog
. -
The
on_key
method updates thecurrent_line
when Enter is pressed and updates the right label in the footer to reflect the line number. -
Run the Application:
-
The app is instantiated and run with
app.run()
.
This example demonstrates:
- Custom Footer: Creating a custom footer with desired layout and content.
-
Reactive Variables:
Using
Reactive
to update the UI dynamically based on changes tocurrent_line
. - Widget Composition: Combining widgets to build a more complex UI.
- Event Handling: Responding to user input (Enter key) to update the application state.
You can now run this code and see how the footer updates the line number as you type into the TextLog!
标签:python,textual,python-textual From: 78814860