实时显示中表格的垂直溢出应滚动内容

a_g*_*est 6 python rich

我正在使用Live显示器来显示随时间增长的内容Table。最终会出现垂直溢出,在这种情况下,我希望最旧的(即最上面的)行消失,而最新的行应与标题一起显示,即内容应滚动。vertical_overflow实时显示的参数提供了一个选项"visible",但这使得表格的标题消失。显然这是一个Table特定的问题,因为标题应该保留,但内容应该滚动。

import time
from rich.live import Live
from rich.table import Table

table = Table()
table.add_column('Time')
table.add_column('Message')

with Live(table, refresh_per_second=5, vertical_overflow='visible'):
    for i in range(100):
        time.sleep(0.2)
        table.add_row(time.asctime(), f'Event {i:03d}')
Run Code Online (Sandbox Code Playgroud)

左侧部分显示了行为vertical_overflow='visible',右侧部分显示了所需的行为:

例子

到目前为止,我使用的解决方法是使用单独的数据结构来保存行,然后每次添加新行时都从头开始创建表。这似乎不是很有效,所以我想知道是否有更好的解决方案。此解决方法对于多行行也失败,因为它将它们计为单行(因此会发生溢出)。

from collections import deque
import os
import time
from rich.live import Live
from rich.table import Table


def generate_table(rows):
    table = Table()
    table.add_column('Time')
    table.add_column('Message')
    for row in rows:
        table.add_row(*row)
    return table


width, height = os.get_terminal_size()
messages = deque(maxlen=height-4)  # save space for header and footer

with Live(generate_table(messages), refresh_per_second=5) as live:
    for i in range(100):
        time.sleep(0.2)
        messages.append((time.asctime(), f'Event {i:03d}'))
        live.update(generate_table(messages))
Run Code Online (Sandbox Code Playgroud)

vvo*_*ejn 2

我最近正在做同样的事情,也找不到内置的解决方案。由于您正在渲染实时显示,因此该表不会超过 100 行,因此效率不应成为问题。

\n

这是我的解决方案。它会重复从顶部删除行,直到表格适合为止。这是通过将一个表放入一个表中来衡量的,Layout如果表不适合,则将其截断底部。

\n
from collections import deque\nimport os\nimport time\nfrom rich.live import Live\nfrom rich.table import Table\nfrom rich.layout import Layout\nfrom rich.console import Console\n\n\ndef generate_table(rows):\n    layout = Layout()\n    console = Console()\n\n    table = Table()\n    table.add_column(\'Time\')\n    table.add_column(\'Message\')\n\n    rows = list(rows)\n\n    # This would also get the height:\n    # render_map = layout.render(console, console.options)\n    # render_map[layout].region.height\n    n_rows = os.get_terminal_size()[1]\n\n    while n_rows >= 0:\n        table = Table()\n        table.add_column(\'Time\')\n        table.add_column(\'Message\')\n\n        for row in rows[-n_rows:]:\n            table.add_row(*row)\n\n        layout.update(table)\n\n        render_map = layout.render(console, console.options)\n\n        if len(render_map[layout].render[-1]) > 2:\n            # The table is overflowing\n            n_rows -= 1\n        else:\n            break\n\n    return table\n\n\nwidth, height = os.get_terminal_size()\nmessages = deque(maxlen=height-4)  # save space for header and footer\n\nwith Live(generate_table(messages), refresh_per_second=5) as live:\n    for i in range(100):\n        time.sleep(0.2)\n        messages.append((time.asctime(), f\'Event {i:03d}\'))\n        live.update(generate_table(messages))\n
Run Code Online (Sandbox Code Playgroud)\n

这里的神奇行是if len(render_map[layout].render[-1]) > 2:。\n这是一种判断表格是否被完整打印的狡猾方法。\n如果是,则最后一个元素render_map[layout].render将如下所示

\n
[\n    Segment(\'\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\', Style()),\n    Segment(\'                                                                         \',)\n]\n
Run Code Online (Sandbox Code Playgroud)\n

或者喜欢

\n
[\n    Segment(\n        \'\n\',\n    )\n]\n
Run Code Online (Sandbox Code Playgroud)\n

但如果它被截断它会看起来像

\n
[\n    Segment(\'\xe2\x94\x82\', Style()),\n    Segment(\' \', Style()),\n    Segment(\n        \'37\',\n        Style(color=Color(\'cyan\', ColorType.STANDARD, number=6), bold=True, italic=False)\n    ),\n    Segment(\'                      \', Style()),\n    Segment(\' \', Style()),\n    Segment(\'\xe2\x94\x82\', Style()),\n    Segment(\'                                                                         \',)\n]\n
Run Code Online (Sandbox Code Playgroud)\n