You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用rich.Style渲染textual.Log彩色文本时滚动条异常求助

问题:Textual Log组件应用Rich Style后滚动条错乱

我尝试使用rich.Style在textual.Log组件中渲染彩色文本,为各行应用Style后,滚动条出现错乱问题。

问题代码

from textual import work
from textual.app import App
from textual.widgets import Log
from rich.style import Style

class BrokenLog(App[None]):
    CSS = "Log { border: solid $accent; }"

    def compose(self):
        yield Log()

    async def on_mount(self):
        self.query_one(Log).write_lines(
            (Style(color="red") if i % 2 else Style(color="green")).render(f"line {i}")
            for i in range(100)
        )

BrokenLog().run()

现象

滚动条显示异常,行宽计算未正确忽略颜色控制序列,导致布局错乱。

使用版本

textual=0.46.0、rich=13.7.0、Python 3.11.4


解决方案

原因

直接调用Style.render()生成的字符串包含终端颜色控制序列,Log组件会将这些控制序列计入文本宽度,进而导致滚动条的行宽计算错误。

正确实现方式

利用Log组件原生支持Rich标记的特性,通过在文本中嵌入颜色标签来实现每行不同颜色,无需直接使用rich.Style:

from textual.app import App
from textual.widgets import Log

class FixedLog(App[None]):
    CSS = "Log { border: solid $accent; }"

    def compose(self):
        yield Log()

    async def on_mount(self):
        log = self.query_one(Log)
        for i in range(100):
            color = "red" if i % 2 else "green"
            # 使用Rich的颜色标记语法
            log.write(f"[color({color})]line {i}[/color]")

FixedLog().run()

或者更简洁的写法,用write_lines配合生成器:

async def on_mount(self):
    self.query_one(Log).write_lines(
        f"[red]line {i}[/red]" if i % 2 else f"[green]line {i}[/green]"
        for i in range(100)
    )

这样Log组件会正确解析颜色标记,忽略控制序列对行宽的影响,滚动条即可正常工作。


内容的提问来源于stack exchange,提问作者frans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 07:17:04