@MasterCopipaster

Как обновить последние две линии в консоли — не затрагиваю другие строки?

У меня есть программа которая выводит данные в консоль, а потом выводит таймер до следующего обновления данных.
По моей задумке вывод должен выглядеть так:

Important data 1
Important data 2
Important data 3
Next update data after 01 minutes 51 seconds ...
To stop the program, press Ctrel+E


Но есть одна проблема, когда строка с таймером становится меньше строки накладываются друг на друга.
Next update data after 55 seconds ...seconds ...

Хотя должно быть
Next update data after 55 seconds ...

Я конечно же решил это довольно топорным и простым способом, просто затирая строку пробелами
Из за чего обновления таймера стало выглядеть нормально.
Но тут возникла проблема собственно которую я и не могу ни как решить, из за строки ниже таймера.
Я не знаю как обновить таймер. т.к. символ возврата каретки будет обновлять только последние строку.

Моя идея по решению даной проблемы была следующая:
Я хотел передвинуть курсор на две строки в верх.
Стереть последние две строки и напечатать новые.
Таким образом таймер обновится и строка с информацией останется.
Но в последнем шаге я потерпел неудачу, я использую ansi-escapes для передвижения курсора, и курсор двигается.
Но консоль как то не правильно обновляется, и я ни как не могу понять в чем тут дело, можете подсказать как вылечить это?

import time
from ansi_escapes import ansiEscapes
import sys

len_line_timer = 0
len_line_info = 0


def timerToString(seconds: int) -> str:
    if seconds is not None:
        seconds = int(seconds)
        d = seconds // (3600 * 24)
        h = seconds // 3600 % 24
        m = seconds % 3600 // 60
        s = seconds % 3600 % 60
        if d > 0:
            return '{:02d}d {:02d}h {:02d}m {:02d}s'.format(d, h, m, s)
        elif h > 0:
            return '{:02d}h {:02d}m {:02d}s'.format(h, m, s)
        elif m > 0:
            return '{:02d} minutes {:02d} seconds'.format(m, s)
        elif s > 0:
            return '{:02d} seconds'.format(s)
    return 'now'


def timer(seconds):
    global len_line_timer
    global len_line_info

    clear_line_timer = ''.join(" " for i in range(len_line_timer))
    clear_line_info = ''.join(" " for i in range(len_line_info))
    line_timer = 'Next update data after ' + timerToString(seconds) + ' ...'
    line_info = 'To stop the program, press Ctrl+E'
    len_line_timer = len(line_timer)
    len_line_info = len(line_info)
    ####################################################################################
    # You need to somehow return the cursor pointer to the beginning of the timer line #
    ####################################################################################
    print(line_timer + '\r', end='')
    print(line_info + '\r', end='')
    sys.stdout.write(ansiEscapes.cursorUp(1) + ansiEscapes.cursorLeft)
    print(clear_line_info + '\r', end='')
    sys.stdout.write(ansiEscapes.cursorUp(1) + ansiEscapes.cursorLeft)
    print(clear_line_timer + '\r', end='')
    sys.stdout.write(ansiEscapes.cursorDown(2) + ansiEscapes.cursorLeft)


    # print("\r\033[2A", end="")


if __name__ == '__main__':
    print("Important data 1")
    print("Important data 2")
    back_timer = 70
    counter = back_timer
    while True:

        timer(counter)

        counter -= 1
        time.sleep(1)
        if counter <= 0:
            counter = back_timer
  • Вопрос задан
  • 82 просмотра
Пригласить эксперта
Ответы на вопрос 1
RimMirK
@RimMirK
Вроде человек. Вроде учусь. Вроде пайтону
import colorama
from colorama.ansi import AnsiCursor
import time

colorama.init()

print(1)
print(4)
print(3)
time.sleep(1)
print(AnsiCursor().UP(2) + str(2))
time.sleep(1)
print(AnsiCursor().DOWN() + str(4))
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы