Textual Rule 控件完全指南:用 `<hr>` 式的分隔线组织终端界面布局

发布时间:2026/9/19 17:34:26

Textual Rule 控件完全指南:用 `<hr>` 式的分隔线组织终端界面布局 Textual Rule 控件完全指南用hr式的分隔线组织终端界面布局【免费下载链接】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 框架内置的Rule控件展开讲解如何用它像 HTML 的hr标签一样在终端界面中分隔内容区块覆盖水平/垂直两种方向的全部线型、Reactive 属性、构造器与类方法、CSS 布局定制以及参数校验与源码实现细节。读完本文你将能够在自己的 Textual 应用中熟练插入、定制和动态切换各种风格的分隔线。Rule 是什么Rule是 Textual 提供的一个分隔类separator控件功能与 HTML 中的hr水平线标签类似用来在视觉上把界面中的不同内容区块分隔开增强布局的层次感与可读性。在 Textual 官方 API 文档docs/widgets/rule.md中Rule 的定位被明确描述为 A rule widget to separate content, similar to ahrHTML tag。Rule 的两个关键特性不可聚焦Focusable否Rule 不参与键盘焦点管理用户无法通过 Tab 键聚焦到它非容器Container否Rule 不能挂载子控件它只是一个纯渲染的装饰性控件。这两个特性使其非常轻量它不发送任何消息Messages、没有绑定按键Bindings、也没有组件类Component Classes职责单一纯粹。快速上手在应用里放置一条分隔线最简单的用法是在compose()中直接yield Rule()然后app.run()启动from textual.app import App, ComposeResult from textual.widgets import Label, Rule class MyApp(App): def compose(self) - ComposeResult: yield Label(上半部分内容) yield Rule() yield Label(下半部分内容) if __name__ __main__: MyApp().run()默认情况下Rule()渲染为一条水平实线line_stylesolid并使用主题的$secondary颜色见下文 DEFAULT_CSS 源码这通常能很好地融入 Textual 自带的主题体系。水平 Rule默认方向与全部线型Rule 的默认方向orientation是horizontal水平。水平方向下Rule 会沿容器宽度方向延伸成一条横线。仓库中的官方示例 docs/examples/widgets/horizontal_rules.py 一次性展示了所有可用的水平线型配合标签标注每种线型的名称from textual.app import App, ComposeResult from textual.containers import Vertical from textual.widgets import Label, Rule class HorizontalRulesApp(App): CSS_PATH horizontal_rules.tcss def compose(self) - ComposeResult: with Vertical(): yield Label(solid (default)) yield Rule() yield Label(heavy) yield Rule(line_styleheavy) yield Label(thick) yield Rule(line_stylethick) yield Label(dashed) yield Rule(line_styledashed) yield Label(double) yield Rule(line_styledouble) yield Label(ascii) yield Rule(line_styleascii) if __name__ __main__: app HorizontalRulesApp() app.run()配套的样式文件 docs/examples/widgets/horizontal_rules.tcss 负责让示例居中并约束布局Screen { align: center middle; } Vertical { height: auto; width: 80%; } Label { width: 100%; text-align: center; }从示例可以看到构造时只需通过line_style参数即可切换线型。line_style一共支持 9 种取值ascii、blank、dashed、double、heavy、hidden、none、solid、thick。其中solid是默认值blank、hidden、none三种在视觉上等效于空白常用于隐藏分隔线但保留布局占位ascii使用纯 ASCII 字符-适合对字符集有严格限制的环境。垂直 Rule侧边栏与列布局的分隔将orientation设为verticalRule 就会变成一条竖线用于在左右分栏布局如侧边栏、双列内容中分隔列。仓库示例 docs/examples/widgets/vertical_rules.py 展示了所有垂直线型from textual.app import App, ComposeResult from textual.containers import Horizontal from textual.widgets import Label, Rule class VerticalRulesApp(App): CSS_PATH vertical_rules.tcss def compose(self) - ComposeResult: with Horizontal(): yield Label(solid) yield Rule(orientationvertical) yield Label(heavy) yield Rule(orientationvertical, line_styleheavy) yield Label(thick) yield Rule(orientationvertical, line_stylethick) yield Label(dashed) yield Rule(orientationvertical, line_styledashed) yield Label(double) yield Rule(orientationvertical, line_styledouble) yield Label(ascii) yield Rule(orientationvertical, line_styleascii) if __name__ __main__: app VerticalRulesApp() app.run()配套样式 docs/examples/widgets/vertical_rules.tcss 中Horizontal容器设定为固定高度比例、标签限定宽度并垂直居中文本从而让竖线与标签在垂直方向完整伸展Screen { align: center middle; } Horizontal { width: auto; height: 80%; } Label { width: 6; height: 100%; text-align: center; }要点垂直 Rule 需要所在的容器有确定的可用高度它才会伸展填满。若容器高度是auto竖线可能没有足够的长度可渲染。Reactive 属性orientation 与 line_styleRule 只有两个 Reactive 属性官方文档的属性表如下docs/widgets/rule.md名称类型默认值描述orientationRuleOrientationhorizontal规则的方向横/竖。line_styleLineStylesolid规则的线型。在源码 src/textual/widgets/_rule.py 中两者的类型别名与 reactive 定义如下RuleOrientation Literal[horizontal, vertical] LineStyle Literal[ ascii, blank, dashed, double, heavy, hidden, none, solid, thick, ] class Rule(Widget, can_focusFalse): orientation: Reactive[RuleOrientation] reactiveRuleOrientation line_style: Reactive[LineStyle] reactiveLineStyle因为二者是 Reactive 属性你可以在运行时直接赋值控件会自动重绘rule Rule() # ... 挂载到界面后运行时动态切换 rule.orientation vertical rule.line_style doublewatch_orientation回调会在方向变化时同步切换控件的 CSS 类-horizontal与-vertical见 src/textual/widgets/_rule.py这两个类正是 DEFAULT_CSS 中不同布局规则的选择器。源码解读Rule 是如何渲染的阅读 src/textual/widgets/_rule.py 可以清楚看到 Rule 的实现细节。1. 线型到字符的映射表每种线型在水平与垂直方向对应不同的 Unicode 制表符_HORIZONTAL_LINE_CHARS { ascii: -, blank: , dashed: ╍, double: ═, heavy: ━, hidden: , none: , solid: ─, thick: █, } _VERTICAL_LINE_CHARS { ascii: |, blank: , dashed: ╏, double: ║, heavy: ┃, hidden: , none: , solid: │, thick: █, }可以推断视觉风格差异正源于这些字符的选择heavy用粗线字符━/┃thick直接用实心块█double用双线字符═/║dashed用间断字符╍/╏ascii则退化为-/|。2. render() 的分发逻辑Rule.render()根据orientation选择字符表并构造对应的可渲染对象def render(self) - RenderResult: if self.orientation vertical: return VerticalRuleRenderable(_VERTICAL_LINE_CHARS[self.line_style], style, self.content_size.height) elif self.orientation horizontal: return HorizontalRuleRenderable(_HORIZONTAL_LINE_CHARS[self.line_style], style, self.content_size.width) else: raise InvalidRuleOrientation(...)HorizontalRuleRenderable将单个字符重复width次拼成一行Segment(self.width * self.character, self.style)VerticalRuleRenderable将单字符段与换行段交替重复height次形成纵向延伸的竖线。线条颜色来自self.rich_style而 rich_style 由 CSS 决定默认取主题色$secondary见 DEFAULT_CSS。3. 内容尺寸的确定Rule 重写了get_content_width与get_content_heightdef get_content_width(self, container, viewport): return container.width if self.orientation horizontal else 1 def get_content_height(self, container, viewport, width): return 1 if self.orientation horizontal else container.height即水平方向占满容器宽度高度固定 1 行垂直方向占满容器高度宽度固定 1 列。这与 DEFAULT_CSS 中的布局规则相互印证Rule { color: $secondary; } Rule.-horizontal { height: 1; margin: 1 0; width: 1fr; } Rule.-vertical { width: 1; margin: 0 2; height: 1fr; }可以看到水平 Rule 上下各留 1 行外边距、宽度为1fr垂直 Rule 左右各留 2 列外边距、高度为1fr。expand True在__init__中设置确保它在分配布局空间时尽量伸展。构造器参数与便捷类方法Rule.__init__的完整签名见 src/textual/widgets/_rule.pyRule( orientation: RuleOrientation horizontal, line_style: LineStyle solid, *, name: str | None None, id: str | None None, classes: str | None None, disabled: bool False, )除两个核心参数外其余参数与所有 Textual 控件一致DOM id、CSS 类、禁用状态等。同时 Rule 提供两个语义化的类方法构造器Rule.horizontal(line_stylesolid, ...)等价于Rule(orientationhorizontal, line_style...)Rule.vertical(line_stylesolid, ...)等价于Rule(orientationvertical, line_style...)。例如yield Rule.vertical(line_styleheavy)在快照测试应用 tests/snapshot_tests/snapshot_apps/rules.py 中就同时使用了位置参数形式Rule(vertical, line_style...)与关键字形式来创建竖线with Vertical(): for rule_style in RULE_STYLES: yield Rule(line_stylerule_style) with Horizontal(): for rule_style in RULE_STYLES: yield Rule(vertical, line_stylerule_style)参数校验无效值会抛出异常Textual 对 Rule 的两个核心参数做了严格校验源码中定义了两种异常InvalidRuleOrientation方向非法时抛出InvalidLineStyle线型非法时抛出。校验逻辑由 reactive 的validate_orientation与validate_line_style钩子实现非法值会被直接拒绝def validate_orientation(self, orientation): if orientation not in _VALID_RULE_ORIENTATIONS: raise InvalidRuleOrientation(fValid rule orientations are {friendly_list(_VALID_RULE_ORIENTATIONS)}) return orientation def validate_line_style(self, style): if style not in _VALID_LINE_STYLES: raise InvalidLineStyle(fValid rule line styles are {friendly_list(_VALID_LINE_STYLES)}) return style注意校验是在赋值时触发的因此无论在构造时还是运行时给orientation/line_style赋非法值都会立刻抛异常。测试文件 tests/test_rule.py 完整覆盖了这四种失败场景async def test_invalid_rule_orientation(): with pytest.raises(InvalidRuleOrientation): Rule(orientationinvalid orientation!) async def test_invalid_rule_line_style(): with pytest.raises(InvalidLineStyle): Rule(line_styleinvalid line style!) async def test_invalid_reactive_rule_orientation_change(): rule Rule() with pytest.raises(InvalidRuleOrientation): rule.orientation invalid orientation! async def test_invalid_reactive_rule_line_style_change(): rule Rule() with pytest.raises(InvalidLineStyle): rule.line_style invalid line style!这两个异常类与类型别名LineStyle、RuleOrientation均从 src/textual/widgets/rule.py 导出可以直接导入使用from textual.widgets.rule import InvalidLineStyle, InvalidRuleOrientation, LineStyle, RuleOrientation用 CSS 定制 Rule 的外观除了线型Rule 作为普通 Widget 同样支持 Textual 的 CSS 体系。常用的定制手段包括颜色color属性决定线条颜色例如Rule { color: $accent; }外边距与尺寸水平 Rule 可通过margin、width调整横线的位置与长短垂直 Rule 可通过height控制伸展范围组合选择器利用方向类Rule.-horizontal/Rule.-vertical分别定制横竖两种形态。例如将某条 Rule 变为较宽幅的强调色横线Rule.emphasis { color: $warning; margin: 1 0; }消息、绑定与组件类官方文档明确说明 Rule 的这三项均为空Messages消息不发送任何消息Bindings按键绑定无绑定Component Classes组件类无组件类。因此在实现自定义行为时你不需要为 Rule 处理任何消息或按键事件它的角色是纯装饰性的。测试与验证仓库通过快照测试保证 Rule 渲染的视觉回归相关用例位于 tests/snapshot_tests/test_snapshots.pytest_rule_horizontal_rules基于docs/examples/widgets/horizontal_rules.py生成快照test_rule_horizontal_rules.svgtest_rule_vertical_rules基于docs/examples/widgets/vertical_rules.py生成快照test_rule_vertical_rules.svgtest_rules基于 tests/snapshot_tests/snapshot_apps/rules.py 一次性渲染 9 种线型 × 横竖两方向test_rules.svg。此外 tests/test_rule.py 覆盖了非法方向与非法线型在构造与运行时赋值两种场景下的异常行为。若要在自己的应用中验证 Rule 行为也可以在测试中使用 Textual 的 Pilot 驱动应用后断言控件属性与渲染结果。小结Rule 是 Textual 中一个轻量、专注的分隔控件默认水平实线通过orientation与line_style两个 Reactive 属性即可在横/竖两个方向、9 种线型间自由切换并支持运行时动态修改作为纯装饰控件它无消息、无绑定、无组件类配合 CSS 的color、margin、width/height等规则可以灵活融入各种布局。无论是表单分区、侧边栏分隔还是日志区块划分Rule都能以最少代码提供清晰的结构化视觉反馈。【免费下载链接】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),仅供参考
延伸阅读

更多相关文章

2026/9/19 17:34:26

基于RIS的隧道无线通信信号增强仿真与经济效益评估

简介:针对隧道场景下RIS辅助无线通信性能优化问题,这份资源提供基于MATLAB的完整仿真复现方案,适合通信工程研究人员、高校师生及无线通信系统设计工程师学习参考。通过28GHz非视距场景下的多RIS部署建模,演示了RIS场强合成原理、…

2026/9/19 17:34:26

全自动洗衣机PLC控制:梯形图与语句表设计实战

简介:面向PLC学习者和自动化从业者的全自动洗衣机控制系统设计文档,完整呈现了基于PLC的洗衣机控制逻辑,涵盖系统启停、进水、强洗/弱洗切换、排水、脱水、循环计数与超时报警等环节。文档按23个网络逐段拆解梯形图与语句表,附有清…

2026/9/19 17:29:26

BrewUI实战:把Homebrew包管理变成可视化掌控

BrewUI这个项目名字一出来,老 mac 用户应该立刻能反应过来——这不就是给 Homebrew 套了个图形界面嘛。作为一个在终端里泡了十几年、用 Homebrew 装了上千个包的人,我最初对这种 GUI 封装是有点不屑的:brew install 一行命令的事&#xff0c…

2026/9/19 18:39:30

机械拆装与结构分析PPT自动化生成:从流程拆解到python-pptx实践

简介:《机械拆装与结构分析》是一份面向机械工程专业学生与实训教师的PPT课件,聚焦减速器拆装与结构分析实验,适用于机械设计、维修及管理等方向的教学实操场景。课件围绕JZQ-250型二级展开式圆柱齿轮减速器和教学用单级圆柱齿轮减速器&#…

2026/9/19 18:39:30

NRF52832 Secure DFU Bootloader深度解析:从签名验证到断电续升

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 18:39:30

C#对接Vector XL驱动:CAN通道配置与端口访问实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 18:34:30

电力系统暂态稳定分析:从试题到仿真建模实战指南

简介:本资源是一套面向电气工程专业本科生及考研学生的电力系统稳定与暂态分析核心习题集,聚焦电力系统安全运行的关键能力训练,涵盖静态稳定判据、等面积定则应用、复合序网构建、潮流计算方法比较、短路故障类型辨析、调压方式识别等高频考…

2026/9/18 14:13:01

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/19 0:03:10

验证 OpenSpec 兼容性,Cursor 的 Token 从 TaoToken 出

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

书桌角落的 Mac mini,OpenClaw 通过 TaoToken 跑任务。

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 0:03:10

oh-my-hermes:打造跨工具的命令编排与插件化工作流

1. 项目概述与设计初衷1.1 它到底是什么先说结论:oh-my-hermes 是一个面向开发者日常终端操作的效率工具套件,核心定位是“把分散在各类命令行工具里的高频操作,统一收拢成一套插件化、可编排的工作流”。项目灵感来源很明显——oh-my-zsh 重…

2026/9/18 14:13:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/18 14:13:02

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/18 14:13:02

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码