ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Textual 0.6.0 发布深度解读:全新 Tree 控件、ListView 与 Placeholder 实战指南

2026/9/19 15:05:02 拓冰建站 浏览量
Textual 0.6.0 发布深度解读:全新 Tree 控件、ListView 与 Placeholder 实战指南 Textual 0.6.0 发布深度解读全新 Tree 控件、ListView 与 Placeholder 实战指南【免费下载链接】textualThe lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser.项目地址: https://gitcode.com/gh_mirrors/te/textual导读Textual 0.6.0 是距上一个版本仅三周后落地的重磅更新其核心是从零重写的 Tree 控件旧的树控件 API 过于复杂且在上千节点时滚动性能明显劣化新实现采用更简洁的 API 与高度可扩展的架构为 DirectoryTree 奠定了基础。同时本版本带来了全新的 ListView 列表控件并修复了 Placeholder 占位组件。读完本文你将掌握 Tree 的节点操作 API、DirectoryTree 的目录事件处理、ListView 与 Placeholder 的完整用法并理解新 Tree 控件在源码层面的可扩展性设计。版本概览Textual 0.6.0 发布于 2022 年 12 月 11 日见 docs/blog/posts/release0-6-0.md 的 front matter距上一版仅 3 周。三个值得关注的变化Tree Control 重写——头号功能API 更简单、规模可扩展ListView 全新控件——支持将任意 Widget 作为列表项Placeholder 修复回归——配合大量布局相关修复。Tree 控件从零重写的头号功能为什么重写旧版 Tree 有两个痛点API 过度复杂以及不可扩展——当节点数达到上千个时滚动会明显变慢。0.6.0 的 Tree 从底层重新设计更简单的 API围绕Tree与TreeNode两个核心类组织日常操作只需add、add_leaf、expand、collapse高度可扩展展开/折叠大尺寸树时不再有明显卡顿视觉增强附带多项外观改进。最简示例官方文档给出的入门示例位于 docs/examples/widgets/tree.py运行后即得一棵展示《沙丘》角色的树from textual.app import App, ComposeResult from textual.widgets import Tree class TreeApp(App): def compose(self) - ComposeResult: tree: Tree[str] Tree(Dune) tree.root.expand() characters tree.root.add(Characters, expandTrue) characters.add_leaf(Paul) characters.add_leaf(Jessica) characters.add_leaf(Chani) yield tree if __name__ __main__: app TreeApp() app.run()保存为tree.py后执行python tree.py即可运行。代码要点Tree(Dune)创建根节点标签为 Dune 的树泛型参数Tree[str]表示节点可携带str类型数据tree.root是树的根TreeNodeexpand()展开根节点以显示其子节点root.add(Characters, expandTrue)添加一个默认展开的子节点add_leaf(Paul)添加叶子节点无子节点、不可展开的终端节点。TreeNode 节点操作 API 深度解读在 0.6.0 的新架构中树的每个节点是TreeNode对象源码定义于 src/textual/widgets/_tree.py它同时承担数据容器与 UI 状态的双重职责。常用操作如下| 方法 | 作用 | 源码位置 | | :- | :- | :- | |add(label, dataNone, *, before..., after..., expandFalse, allow_expandTrue)| 添加一个子节点可指定插入位置before/after支持传索引或节点、是否展开、是否允许用户展开 | _tree.py | |add_leaf(label, dataNone, ...)| 添加一个叶子节点终端节点 | _tree.py | |expand()/expand_all()| 展开本节点 / 展开本节点及所有后代 | _tree.py | |collapse()/collapse_all()| 折叠本节点 / 折叠本节点及所有后代 | _tree.py | |toggle()/toggle_all()| 切换展开/折叠状态 | _tree.py | |set_label(label)/label属性 | 更新节点标签接受str或Text修改后自动刷新节点渲染 | _tree.py | |children属性 | 以只读序列视图访问子节点 | _tree.py |值得注意的是TreeNode持有data字段_tree.py因此 Tree 是一个泛型控件可以把任意 Python 对象挂在节点上实现树形数据 树形展示的映射这正是DirectoryTree复用 Tree 来承载DirEntry目录项的基础。从源码结构看新 Tree 的可扩展性并非依赖虚拟化而是通过缓存渲染行实现的_tree.py中定义了LineCacheKey类型与LRUCachesrc/textual/widgets/_tree.py节点状态变更如展开/折叠、标签修改通过_invalidate()、_refresh_node()等方法精准地使缓存失效避免整树重绘从而保证大树的滚动流畅。用 Tree 导航 JSON 数据发布文档特别演示了用 Tree 浏览 JSON 数据的示例 examples/json_tree.py把 JSON 的键/值递归转换为树节点用户即可用键盘或鼠标在终端中逐层展开浏览任意结构的 JSON 文档。这类数据天然呈树状的场景文件系统、菜单、配置层级、DOM 结构等正是新 Tree 的主要用武之地。DirectoryTree基于 Tree 的目录浏览器Tree 控件构成了 DirectoryTree 的基础该控件在 0.6.0 中同步更新。DirectoryTree 继承自Tree[DirEntry]src/textual/widgets/_directory_tree.py展示文件系统目录结构。最简用法见 docs/examples/widgets/directory_tree.pyfrom textual.app import App, ComposeResult from textual.widgets import DirectoryTree class DirectoryTreeApp(App): def compose(self) - ComposeResult: yield DirectoryTree(./) if __name__ __main__: app DirectoryTreeApp() app.run()DirectoryTree(./)以当前目录为根渲染整棵目录树用户可展开文件夹、选中文件。官方示例 examples/code_browser.py 展示了它与代码浏览器的结合左侧目录树选文件、右侧展示文件内容。目录选择事件与普通 Tree 不同DirectoryTree 为文件与目录分别派发消息_directory_tree.pyFileSelected——文件被选中时派发携带node与path在子类或父组件中用on_directory_tree_file_selected处理DirectorySelected——目录被选中时派发携带node与path用on_directory_tree_directory_selected处理。两个消息的control属性都指回触发它的Tree。典型写法from textual.app import App, ComposeResult from textual.widgets import DirectoryTree class CodeBrowser(App): def compose(self) - ComposeResult: yield DirectoryTree(./) def on_directory_tree_file_selected(self, event: DirectoryTree.FileSelected) - None: # 用 event.path 读取文件内容并展示 self.log(fSelected: {event.path})组件类Component Classes与图标DirectoryTree 定义了 4 个组件类供 CSS 定制_directory_tree.pydirectory-tree--extension文件扩展名、directory-tree--file文件、directory-tree--folder文件夹、directory-tree--hidden隐藏项。其内置样式还使用 emoji 图标区分节点状态展开的文件夹 、文件夹 、文件 _directory_tree.py。内置默认 CSS 让文件夹加粗、扩展名斜体、隐藏项变暗且提供了针对 ANSI 终端配色的一整套替代样式。ListView可容纳任意 Widget 的列表控件0.6.0 新增 ListView 控件用于在列表中导航与选择项目。它的关键设计是列表项本身可以是 Widget因此非常适合作为更复杂控件的构建平台例如在列表项中嵌入图标、进度条或自定义渲染内容。官方示例见 docs/examples/widgets/list_view.py 与配套样式 docs/examples/widgets/list_view.tcssfrom textual.app import App, ComposeResult from textual.widgets import Footer, Label, ListItem, ListView class ListViewExample(App): CSS_PATH list_view.tcss def compose(self) - ComposeResult: yield ListView( ListItem(Label(One)), ListItem(Label(Two)), ListItem(Label(Three)), ) yield Footer() if __name__ __main__: app ListViewExample() app.run()配套的list_view.tcss将列表居中并限定宽度同时给Label添加内边距Screen { align: center middle; } ListView { width: 30; height: auto; margin: 2 2; } Label { padding: 1 2; }用法要点每个列表项是一个ListItem内部可以嵌套任意 Widget这里是Label也可以是Button、ProgressBar等在应用底部添加Footer可获得操作提示如上下移动光标、回车选择样式上注意给ListView设置合适的width与height: auto让列表自适应内容高度。PlaceholderUI 布局设计期的占位组件Placeholder 自上次大规模 CSS 更新后一度损坏0.6.0 将其修复并做了打磨详见 docs/widgets/placeholder.md。它的设计用途在设计 UI 时用它代替尚未实现的业务组件先搭好布局骨架。特性包括颜色自动循环——相邻的 Placeholder 会自动使用不同配色便于区分彼此点击循环显示内容——点击某个占位块可在组件 ID、组件尺寸与 lorem ipsum 占位文本三种显示模式间切换variant 参数——可指定size显示尺寸或text显示占位文本等变体。官方示例docs/examples/widgets/placeholder.py构建了一个复杂的网格布局演示from textual.app import App, ComposeResult from textual.containers import Container, Horizontal, VerticalScroll from textual.widgets import Placeholder class PlaceholderApp(App): CSS_PATH placeholder.tcss def compose(self) - ComposeResult: yield VerticalScroll( Container( Placeholder(This is a custom label for p1., idp1), Placeholder(Placeholder p2 here!, idp2), Placeholder(idp3), Placeholder(idp4), Placeholder(idp5), Placeholder(), Horizontal( Placeholder(variantsize, idcol1), Placeholder(varianttext, idcol2), Placeholder(variantsize, idcol3), idc1, ), idbot, ), Container( Placeholder(varianttext, idleft), Placeholder(variantsize, idtopright), Placeholder(varianttext, idbotright), idtop, ), idcontent, ) if __name__ __main__: app PlaceholderApp() app.run()配套样式 docs/examples/widgets/placeholder.tcss 展示了用网格布局layout: grid、grid-size、row-span、column-span和1fr弹性宽度把占位块拼成复杂页面骨架的手法。这里Placeholder可以通过id精确定位用 CSS 控制每个块的跨行跨列先确认布局效果再逐个替换为真实组件。修复与其他变化发布文档提到本版本一如既往包含大量修复主要集中在布局layout相关问题上。0.6.0 的详细变更可查阅仓库根目录的 CHANGELOG.md。由于 Tree 控件重写、Placeholder 回归布局引擎也经历了一轮收敛这些修复为后续版本的稳定性奠定了基础。小结Textual 0.6.0 的三个主角各司其职Tree提供了简洁、可扩展的树形数据展示 API是终端中呈现层级结构的通用答案其渲染行缓存设计见 src/textual/widgets/_tree.py保证了大规模节点的流畅滚动DirectoryTree在 Tree 之上直接派生出文件浏览能力并通过FileSelected/DirectorySelected消息与业务逻辑解耦见 src/textual/widgets/_directory_tree.pyListView与Placeholder分别解决可交互列表与布局骨架设计两个高频需求。如果你正在用 Textual 构建涉及文件浏览、JSON 查看器、设置面板等场景的应用这三个组件可以显著加快原型到成品的速度。相关的树控件回归测试覆盖于 tests/tree/ 目录下可作为深入理解控件行为的参考。【免费下载链接】textualThe lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser.项目地址: https://gitcode.com/gh_mirrors/te/textual创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考