Это можно сделать с помощью вот такого пользовательского класса WindowOutput:
class WindowOutput:
def __init__(self, window):
self.window = window
self.window.scrollok(True) # разрешает прокрутку окна
self.line = 0
self._text = ""
def write(self, text):
self._text += text
if '\n' in text:
lines = self._text.split('\n')
for line in lines[:-1]: # обработка всех завершенных строк
self.window.addstr(line + '\n')
self.window.refresh()
self._text = lines[-1] # сохраняет любые оставшиеся строки
def flush(self):
if self._text:
self.window.addstr(self._text)
self.window.refresh()
self._text = ""
Предположим, что у вас есть два окна curses без бордюра. Первое окно сверху, в переменной w1, высотой в одну строку, второе окно ниже, занимающее все остальное пространство экрана, в переменной w2. И нам надо, чтобы функция print выводила сообщения в нижнее окно w2.
Вспомогательные функции:
# Функция определяет общий размер экрана консоли в символах:
def get_screen_size():
try:
# Инициализация библиотеки curses:
screen = curses.initscr()
# Получение высоты и ширины экрана:
height, width = screen.getmaxyx()
# Очистка curses:
curses.endwin()
return height, width
except Exception as e:
print(f"Error getting screen size: {e}")
return None, None
# Функция создает окно curses заданного размера,
# с определенным положением на экране консоли:
def create_window(height=None, width=None, y=0, x=0, has_border=True):
try:
# Initialize curses
screen = curses.initscr()
curses.start_color()
curses.noecho()
curses.cbreak()
screen.keypad(True)
# Если размеры окна не указаны, то используется экран целиком:
if height is None or width is None:
max_height, max_width = screen.getmaxyx()
height = height or max_height
width = width or max_width
# Создание окна:
window = curses.newwin(height, width, y, x)
if has_border:
window.box()
window.refresh()
return screen, window
except Exception as e:
curses.endwin()
print(f"Error creating window: {e}")
return None, None
# Функция очистки:
def cleanup_curses(screen):
if screen:
screen.keypad(False)
curses.nocbreak()
curses.echo()
curses.endwin()
Пример функции, которая создает окна w1, w2 и настраивает вывод функции print в окно w2:
def init_interface():
height, width = get_screen_size()
w1h = 1 # высота окна w1
global s1, w1
s1, w1 = create_window(w1h, width, 0, 0, has_border=False)
w2h = height - w1h # высота окна w2
global s2, w2
s2, w2 = create_window(w2h, width, w1h, 0, has_border=False)
global original_stdout
# Сохранение оригинального вывода консоли
# для последующего восстановления:
original_stdout = sys.stdout
sys.stdout = WindowOutput(w2)
Эта функция возвращает вывод функции print в оригинальное состояние:
def revert_interface():
sys.stdout = original_stdout
cleanup_curses(s1)
cleanup_curses(s2)
Как это работает:
if __name__ == "__main__":
# Здесь print печатает как обычно:
print("Обычная печать")
myw.init_interface()
# Теперь print выводит сообщения в окно w2:
print("Вывод сообщений перенаправлен")
myw.revert_interface()
print("Печать возвращена обратно в stdout")