Description
Description:
When popping one of the secondary screens, the TCSS properties of the popped screen get applied to the main screen. In this dummy example the button background color changes. This happens if the Screens share the same structure and the .tcss
is defined with the widget class name. (Notice that I didn't try to use the same tcss class or the same id for widgets in different screens).
Expected Behavior:
After popping a Screen
, all TCSS styles associated with it should be removed. The MainScreen
's buttons should display styles defined in app.tcss
without any residual styles from the popped screen.
Actual Behavior:
Button colors from second.tcss
or first.tcss
(secondary screen) persist and are applied to the MainScreen
's buttons after the screen is dismissed.
Environment:
- Operating System: Linux 6.13.0-rc1-1-MANJARO
- Library Version: 0.88.0
- Python Version: 3.12.7
app.py
:
from textual import on
from textual.app import App, ComposeResult
from textual.widgets import Button, Label, Placeholder
from textual.containers import Vertical
from textual.screen import Screen
from textual.containers import (
Horizontal,
Vertical,
)
class Screen1(Screen):
"""Screen to create a new configuration for the application."""
CSS_PATH = "first.tcss"
def compose(self) -> ComposeResult:
with Vertical():
yield Label("Welcome to the first screen")
yield Button("Dummy Button")
yield Button("Dummy Button")
yield Horizontal(
Button.error("Cancel", id="cancel"),
)
@on(Button.Pressed, "#cancel")
def on_button_pressed(self, event: Button.Pressed) -> None:
self.app.pop_screen()
class Screen2(Screen):
CSS_PATH = "second.tcss"
def compose(self) -> ComposeResult:
with Vertical():
yield Label("Welcome to the second screen")
yield Button("Dummy Button")
yield Button("Dummy Button")
yield Horizontal(
Button.error("Cancel", id="cancel"),
)
@on(Button.Pressed, "#cancel")
def on_button_pressed(self, event: Button.Pressed) -> None:
self.app.pop_screen()
class MainScreen(Screen):
"""Main Screen of the application"""
def compose(self) -> ComposeResult:
yield Vertical(
Label("Welcome to MainScreen!"),
Button("Button 1", id="button-1"),
Button("Button 2", id="button-2"),
)
def on_button_pressed(self, event: Button.Pressed) -> None:
match event.button.id:
case "button-1":
self.app.push_screen("screen-1")
case "button-2":
self.app.push_screen("screen-2")
class MainApp(App):
"""Main Application"""
CSS_PATH = "app.tcss"
SCREENS = {
"main": MainScreen,
"screen-1": Screen1,
"screen-2": Screen2,
}
async def on_mount(self) -> None:
"""Set the initial screen."""
await self.push_screen("main")
if __name__ == "__main__":
MainApp().run()
app.tcss
:
Screen{
align: center middle;
content-align: center middle;
background: gray;
}
Screen > Vertical{
width: auto;
height: auto;
align: center middle;
content-align: center middle;
background: black;
}
Screen > Vertical > Button{
width: 30;
height: auto;
margin: 1 1;
background: gray;
}
Screen > Vertical > Label {
min-width: 1fr;
height: auto;
align: center middle;
content-align: center middle;
}
firts.tcss
:
Screen{
align: center middle;
content-align: center middle;
}
Screen > Vertical{
width: auto;
height: auto;
align: center middle;
content-align: center middle;
}
Screen > Vertical > Button{
width: 30;
height: auto;
margin: 1 1;
background: green;
}
Screen > Vertical > Label {
min-width: 1fr;
height: auto;
align: center middle;
content-align: center middle;
}
second.tcss
:
Screen {
layout: grid;
grid-size: 3 4;
grid-rows: 1fr;
grid-columns: 1fr;
grid-gutter: 1;
}
Screen > Vertical{
width: auto;
height: auto;
align: center middle;
content-align: center middle;
}
Screen > Vertical > Button{
width: 30;
height: auto;
margin: 1 1;
background: blue;
}
Screen > Vertical > Label {
min-width: 1fr;
height: auto;
align: center middle;
content-align: center middle;
}