I'm trying to render colored text inside a textual.Log
widget using rich.Style
, but somehow the scrollbar gets scrambled when applying a Style
to the individual lines.
Here is my code:
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()
And here is what the result looks like:
I suspect the width of the lines to be computed without the control sequences, but I don't know how to tell the Log
widget to take them into account.
Am I doing something wrong? Is there another way to draw lines in a Log
window with different color each?
I'm using textual=0.46.0
and rich=13.7.0
with Python 3.11.4
As a Rule, Textual won't work with ansi escape sequences it didn't generate itself. You are also using Log
which is designed for simple text, and doesn't support color.
You can use RichLog
which does support anything Rich can render. The following will print alternating colors:
from textual import work
from textual.app import App
from textual.widgets import RichLog
from rich.text import Text
class FixedLog(App[None]):
CSS = "Log { border: solid $accent; }"
def compose(self):
yield RichLog()
async def on_mount(self):
log = self.query_one(RichLog)
for i in range(100):
log.write(Text(f"line {i}", style="red" if i%2 else "green"))
FixedLog().run()