[Python] Use `StaticRenderer` subclass to render a sequence of matrices in python asciimatics...

Discussão em 'Python' iniciado por Stack, Maio 4, 2025.

  1. Stack

    Stack Membro Participativo

    background


    I am trying implement a subclass of StaticRenderer that can render a 2d matrix of random characters over a set duration, similar to how gifs can be looped using renderers.ColourImageFile(StaticRenderer).

    I want to use this subclass as the renderer argument of the Print(Effect) class' instantiator, similar to this example.

    code


    This is what I have implemented so far (i am setting the matrix to be the height and width of the terminal):

    from asciimatics.screen import ManagedScreen, Screen
    from asciimatics.scene import Scene
    from asciimatics.effects import Print
    from asciimatics.renderers import StaticRenderer
    from asciimatics.exceptions import ResizeScreenError

    import random
    import time
    import sys


    class RandomMatrixRenderer(StaticRenderer):
    def __init__(self, screen: Screen):
    super(RandomMatrixRenderer, self).__init__()
    self._width = screen.width
    self._height = screen.height
    self._matrix = self._generate_random_matrix()
    self._screen = screen

    def _generate_random_matrix(self):
    chars = "!@#$%^&*()_+=-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    matrix = [
    [random.choice(chars) for _ in range(self._width)]
    for _ in range(self._height)
    ]
    return matrix

    def render_now(self):
    for y in range(self._height):
    for x in range(self._width):
    self._screen.print_at(
    self._matrix[y][x],
    x,
    y,
    colour=random.randint(0, 7),
    bg=random.randint(0, 7),
    )


    def random_matrix(screen):
    while True:
    effect = Print(screen, x=0, y=0, renderer=RandomMatrixRenderer(screen))
    screen.play([Scene([effect])], repeat=False)
    time.sleep(0.1) # Wait for 1 second before showing the next matrix


    def main():
    with ManagedScreen() as screen:
    random_matrix(screen)


    if __name__ == "__main__":
    while True:
    try:
    main()
    sys.exit(0)
    except ResizeScreenError:
    pass


    problem


    However, I am encountering this error:

    Traceback (most recent call last):
    File "/home/marcu/resources/tutorials/asciimatics/waves/matrix_render.py", line 55, in <module>
    main()
    File "/home/marcu/resources/tutorials/asciimatics/waves/matrix_render.py", line 49, in main
    random_matrix(screen)
    File "/home/marcu/resources/tutorials/asciimatics/waves/matrix_render.py", line 43, in random_matrix
    screen.play([Scene([effect])], repeat=False)
    File "/home/marcu/resources/tutorials/asciimatics/.venv/lib/python3.12/site-packages/asciimatics/screen.py", line 1602, in play
    self.draw_next_frame(repeat=repeat)
    File "/home/marcu/resources/tutorials/asciimatics/.venv/lib/python3.12/site-packages/asciimatics/screen.py", line 1705, in draw_next_frame
    effect.update(self._frame)
    File "/home/marcu/resources/tutorials/asciimatics/.venv/lib/python3.12/site-packages/asciimatics/effects.py", line 63, in update
    self._update(frame_no)
    File "/home/marcu/resources/tutorials/asciimatics/.venv/lib/python3.12/site-packages/asciimatics/effects.py", line 334, in _update
    image, colours = self._renderer.rendered_text
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/home/marcu/resources/tutorials/asciimatics/.venv/lib/python3.12/site-packages/asciimatics/renderers/base.py", line 165, in rendered_text
    return (self._plain_images[index],
    ~~~~~~~~~~~~~~~~~~^^^^^^^
    IndexError: list index out of range


    Does this have to do with the parameters stop_frame and speed in the Effect class? Or is there an issue with my matrix input?

    Continue reading...

Compartilhe esta Página