gh-75733: Show IDLE's trees in a ttk.Treeview - #157029
Open
serhiy-storchaka wants to merge 1 commit into
Open
Conversation
idlelib.tree drew its rows on a canvas, with hardcoded pixel sizes that fit neither every font nor every monitor, an icon on every row, and bindings of its own for clicks and scrolling. It now wraps a ttk.Treeview, which takes its row height from the configured font and its indicators, colors and keys from ttk and the theme. Converted: the Module and Path browsers, Debug => Stack Viewer, the object browsers, and the stack, Locals and Globals panes of the Debug Control window. Rows carry more than a text now: an item fills the columns of its row with GetValues, and says with GetTags what kind of row it is, which is how the stack views show a frame as module, function, line and source, and how the Path Browser tells a directory, a package and a module apart. The stack pane of the debugger marks the frame it stopped in with a drawn arrow instead of a "> " in front of the text. The Locals and Globals panes are read-only tables, as editing them never reached the objects in the user process (pythongh-69184). The Module Browser shows no icons, its text saying already whether a row is a class or a function (pythongh-69277). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Sep 6, 2026
Member
Author
|
Trying it by hand. Each module runs its unit tests and then opens its window:
In a running IDLE ( def inner(n): return 1/n
def outer(n): return inner(n)
outer(0)and press Step until you are inside Worth looking at:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
idlelib.treedrew every row on a canvas: hardcoded pixel sizes that fit neither every font nor every monitor, an icon on every row whether it helped or not, and its own bindings for clicks and scrolling. This replaces the drawing with attk.Treeview, which takes its row height from the configured font and its indicators, colours and keys from ttk and the theme. That is the fix for the HiDPI clipping in this issue, and it removes the two blockers you listed: rows no longer need an icon, and a click no longer has to be handled by the tree itself.The module keeps its name —
idlelib/tree.pyis nowScrolledTreeview(attk.Treeviewwith scrollbars, coloured from the configuration) andTreeWidget(a tree ofTreeItems on top of it, asking an item for its children only when its row is opened).test_tree.pyholds the tests for it.Converted, in one commit because they share the widget: the Module and Path browsers, Debug ▸ Stack Viewer, the object browser, the remote stack viewer the Shell opens for a subprocess exception, and the stack, Locals and Globals panes of the Debug Control window. The stack pane was a
ScrolledListlistbox with its own scrollbar, popup menu and key bindings, all of which ttk provides.The item protocol gains two methods and loses two:
GetValues()fills the columns after the tree column, so the stack views show a frame as module, function, line and source rather than one glued string, and the Locals/Globals panes are name/value tables.GetTags()says what kind of row an item is, and the tree that shows it decides what a kind looks like. The Path Browser uses it to mark directories, packages and modules with the icons already inIcons/(so a package row no longer needs": package"); the Module Browser marks nothing.GetIconName()andGetSelectedIconName()go: the canvas drew an image on every row and these chose which, while a Treeview draws none unless asked.plusnode.gifandminusnode.gifgo with them, as ttk draws the indicators itself.Also closed by this, since they cannot be done separately once the drawing changes:
The debugger's stack pane marks the frame it stopped in with an arrow and a bold row instead of prefixing the text with
"> ", so rows no longer shift by two characters and the marker survives selecting another row. The arrow is drawn in code rather than read from a file, so it follows the configured font size and the theme's foreground — a shipped bitmap would be black on IDLE Dark.