pythonrichpython-textual

Bug or wrong usage? Scrollbar broken for textual.Log when printing styled (coloured) lines


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:

enter image description here

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


Solution

  • 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()