Closed as not planned
Closed as not planned
Description
Worth mentioning: this happens on the revision d9f7ffd, because it includes a fix for other crashes (#5641)
Sorry, but I do not yet have an MRE that can reproduce the problem. This happens when pushing/dismissing a screen quickly enough. I've included some code that presents a similar situation.
Maybe related: #5629
In a real scenario spamming LMB on "Show dialog" causes the dialog to be showed and closed again and again. After a while, it crashes with RecursionError.
from __future__ import annotations
from datetime import datetime
from textual import on, work
from textual.app import App, ComposeResult
from textual.containers import Horizontal, Vertical, VerticalScroll
from textual.events import Click, Mount
from textual.screen import ModalScreen
from textual.widgets import Button, Static
class Dialog(ModalScreen):
DEFAULT_CSS = """
Dialog {
align: center middle;
background: $background 85%;
#dialog-content {
border-title-style: bold;
border-title-color: $text;
border-title-background: $primary;
border: $primary outer;
background: $panel 80%;
padding: 1;
width: 50%;
height: auto;
}
}
"""
def __init__(self, item: str) -> None:
super().__init__()
self._item = item
def compose(self) -> ComposeResult:
with Vertical(id="dialog-content"):
yield Static("This is a dialog")
yield Static(f"You clicked on {self._item}")
data = Static("", id="data")
data.loading = True
yield data
yield Button("Close", name="close", id="close-dialog")
@property
def data_widget(self) -> Static:
return self.query_exactly_one("#data", Static)
@on(Mount)
def schedule_data_updating(self) -> None:
self.set_interval(1, self._update)
@on(Button.Pressed, "#close-dialog")
def close_by_button(self) -> None:
self.dismiss()
@on(Click)
def close_by_clicking_outside(self, event: Click) -> None:
"""Close the Dialog if the user clicks outside the modal content."""
if self.get_widget_at(event.screen_x, event.screen_y)[0] is self:
self.dismiss()
@work(name="update data worker")
async def _update(self) -> None:
data_widget = self.data_widget
data_widget.loading = False
data_widget.update(f"Data loaded - {datetime.now()}")
class ExampleApp(App):
DEFAULT_CSS = """
Button {
border: none !important;
&:hover {
border: none !important;
}
}
.item {
height: auto;
.item-name {
width: auto;
}
}
"""
def compose(self) -> ComposeResult:
with VerticalScroll():
for i in range(30):
with Horizontal(classes="item"):
item_name = f"item {i}"
yield Static(item_name, classes="item-name")
yield Button("Show dialog", name=item_name, id="push-dialog")
@on(Button.Pressed, "#push-dialog")
def push_dialog(self, event: Button.Pressed) -> None:
self.push_screen(Dialog(event.button.name))
if __name__ == "__main__":
ExampleApp().run()
Metadata
Metadata
Assignees
Labels
No labels