-
Notifications
You must be signed in to change notification settings - Fork 826
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
self.app.uninstall_screen()
does not delete child nodes
#1580
Comments
I was having a little bit of trouble following quite how your app was holding together, so I've attempted to write a standalone example of what I think you're seeing. Note that this doesn't push or pop screens, it only installs or uninstalls them. from textual.app import App, ComposeResult
from textual.containers import Vertical, Horizontal
from textual.widgets import Header, Footer, Static, Label
from textual.screen import Screen
from textual.binding import Binding
from rich.pretty import Pretty
class ChildScreen( Screen ):
def compose( self ) -> ComposeResult:
"""Compose the child widgets."""
yield Label( "Press space to make me go away", id="only-on-child" )
class Display( Static, can_focus=True ):
pass
class DOMView( Display ):
pass
class ScreenView( Display ):
pass
class QueryResult( Display ):
pass
class ScreenAndDomApp( App[ None ] ):
CSS = """
.box {
border: round yellow;
}
.box:focus-within {
border: double yellow;
}
Horizontal > Vertical {
width: 1fr;
}
"""
BINDINGS = [
Binding( "i", "install", "Install Screen" ),
Binding( "u", "uninstall", "Uninstall Screen" )
]
def __init__( self ) -> None:
super().__init__()
self.screen_id = 0
self.screen_names: list[ str ] = []
def compose( self ) -> ComposeResult:
yield Header()
yield Vertical(
Vertical( DOMView(), classes="box" ),
Horizontal(
Vertical( ScreenView(), classes="box" ),
Vertical( QueryResult(), classes="box" )
)
)
yield Footer()
@property
def installed_screens( self ):
return [ ( k, v ) for k, v in self._installed_screens.items() ]
def refresh_panels( self ) -> None:
self.query_one( DOMView ).update( self.tree )
self.query_one( ScreenView ).update( Pretty( self.installed_screens ) )
self.query_one( QueryResult ).update( Pretty( list( self.query( "#only-on-child" ) ) ) )
def on_mount( self ) -> None:
self.refresh_panels()
def action_install( self ) -> None:
self.screen_names.append( f"child-{ self.screen_id}" )
self.screen_id += 1
self.install_screen( ChildScreen(), self.screen_names[ -1 ] )
self.refresh_panels()
def action_uninstall( self ) -> None:
if self.screen_names:
self.uninstall_screen( self.screen_names.pop() )
self.refresh_panels()
if __name__ == "__main__":
ScreenAndDomApp().run() I am seeing behaviour I wouldn't have expected. Here's what happens when I install 5 screens then uninstall them again: The top panel can be ignored for the moment, it's just a dump of the whole DOM as a tree. Left bottom is the list of installed screens; so it's showing that I no longer have screens installed. Bottom right is performing a query on a widget that is only on the screen I'm installing, and which has subsequently been removed as many times as it was installed. I don't have an answer for this at the moment, but I just wanted to get a good stand-alone example of the problem created and recorded here. |
I think there may be some confusion about what it means to Installing a screen gives it a name and prevents Textual from closing it when you If you want a screen to act like a modal dialog you can use |
Docs have been expanded in #1778 |
Don't forget to star the repository! Follow @textualizeio for Textual updates. |
Please give a brief but clear explanation of the issue.
So, I have a
Back
button, that do:I need it to open the file, do something with this file, and go back. But when I do
install_screen('csv-file-editor') -> install_screen('csv-file-scren') -> self.app.query_one('#csv-file-editor')
- I've get an error that found to many DOM nodes.This behavior can be simply fixed by
self.screen.query_one()
instead ofself.app.query_one()
, but this is really looks like a bug, becauseuninstall_screen()
should alsouninstall
all sub-widgets that was incompose
What Operating System are you running on?
Windows 10 21H2
Feel free to add screenshots and/or videos. These can be very helpful!
Outputs:
And as you can see - screen
CsvFileEditorScreen
was uninstalled, but widget, that was installed incompose
section was not uninstalled, which creates useless objects in memoryP.S.
IDK why, but
Traceback output
cuttedes)
from430 │ │ │ raise Exception(self.app.screen_stack, self.app.query('#csv-data-table').nodes)
, this is not my modification - it's a real output. Probably one more bug to solve? :)The text was updated successfully, but these errors were encountered: