textual icon indicating copy to clipboard operation
textual copied to clipboard

Can't Tree.select_node with newly added node

Open davetapley opened this issue 8 months ago • 5 comments

select_node doesn't work on on an add_leaf in one update cycle.

Can workaround with run_worker, see works vs doesn't work comments.

MRE:

from textual.binding import Binding
from textual.app import App, ComposeResult
from textual.widgets import Tree, Footer


class TreeApp(App[None]):

    BINDINGS = [
        Binding(key="p", action="paul", description="Paul"),
        Binding(key="w", action="worm", description="Uh oh"),
        Binding(key="r", action="ride", description="Kwisatz Haderach"),
    ]

    def compose(self) -> ComposeResult:
        tree: Tree[dict[str, str]] = Tree("Dune")

        tree.root.add_leaf("Paul")
        tree.root.add_leaf("Jessica")
        tree.root.add_leaf("Chani")
        tree.root.expand()

        yield tree
        yield Footer()

    def action_paul(self):
        tree = self.query_one(Tree)
        tree.select_node(self.paul) # Works

    def action_worm(self):
        tree = self.query_one(Tree)
        node = tree.root.add_leaf("Worm")
        tree.select_node(node)  # Doesn't work

    def action_ride(self):
        tree = self.query_one(Tree)
        node = tree.root.add_leaf("Shai-Hulud")

        async def select():
            tree.select_node(node) # Works

        self.run_worker(select)


if __name__ == "__main__":
    app = TreeApp()
    app.run()

Textual Diagnostics

Versions

Name Value
Textual 0.39.0
Rich 13.3.3

Python

Name Value
Version 3.11.4
Implementation CPython
Compiler MSC v.1934 64 bit (AMD64)
Executable C:\Users\dave.venvs\ng\Scripts\python.exe

Operating System

Name Value
System Windows
Release 10
Version 10.0.20348

Terminal

Name Value
Terminal Application vscode (1.83.1)
TERM Not set
COLORTERM truecolor
FORCE_COLOR Not set
NO_COLOR Not set

Rich Console options

Name Value
size width=93, height=68
legacy_windows False
min_width 1
max_width 93
is_terminal True
encoding utf-8
max_height 68
justify None
overflow None
no_wrap False
highlight None
markup None
height None

Feel free to add screenshots and / or videos. These can be very helpful!

davetapley avatar Oct 17 '23 03:10 davetapley

I can't reproduce this using your MRE. What exactly are you doing when running the MRE that's causing the problem?

Could you describe in more detail what you mean when you say it doesn't work?

Is there a stack trace you can share, or does it just not behave as you'd expect?

darrenburns avatar Oct 17 '23 16:10 darrenburns

If you press w this adds the "Worm" node but the select_node on the next line doesn't work, instead it selects "Dune".

Possibly another case of work happening on idle so needs acall_after_refresh?

TomJGooding avatar Oct 17 '23 17:10 TomJGooding

@TomJGooding Sure seems like it!

darrenburns avatar Oct 17 '23 17:10 darrenburns

@darrenburns The problem is that node._line for the new "Worm" node is -1 when select_node is called.

It looks like the line number for each node is only calculated in _build from a call in _on_idle.

You could explicitly call _build when a new node is added, but I'm not sure that's the proper fix?

TomJGooding avatar Oct 18 '23 19:10 TomJGooding

Yes @TomJGooding, thanks for clarifying 🙏🏻 I've updated MRE to be less confusing.

Your analysis makes sense. I think figuring out when _build is going to be... wait for it... a real can of worms 🙃

davetapley avatar Oct 20 '23 03:10 davetapley