使用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
相关产品推荐
相关产品推荐

