Найти - Пользователи
Полная версия: Простой пример на curses. Не могу понять где ошибка
Начало » Python для новичков » Простой пример на curses. Не могу понять где ошибка
1
__sirroko
Привет!

Написал простой тестовый примерчик и не могу понять, почему не работает ф-я up_down(inc)

И, если кто-нибудь подскажет как более правильно написать менюшку, по которой можно будет передвигать с помощью стрелок (так что бы строки подсвечивались), буду благодарен)

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import curses
def init_curses():
    stdscr = curses.initscr()
    
    curses.noecho()
    curses.cbreak()
    stdscr.keypad(1)
    curses.start_color()
    curses.init_pair(1, curses.COLOR_YELLOW, curses.COLOR_BLACK)
    stdscr.bkgd(curses.color_pair(1))
    stdscr.refresh()
    
    return stdscr
    
def show_menu(stdscr):
    stdscr.clear()
    stdscr.box()
    stdscr.addstr(1,1, '1')
    stdscr.addstr(2,1, '2')
    stdscr.addstr(3,1, '3')
    stdscr.addstr(4,1, 'Q:Exit')
    stdscr.refresh()
    
def up_down(inc):
    stdscr.clear()
    stdscr.box()
    if inc == 1:
        stdscr.addstr(10,1, 'key_up')
    elif inc == -1:
        stdscr.addstr(11,1, 'key_down')
    stdscr.refresh()
   
stdscr = init_curses()
while True:
    show_menu(stdscr)
    
    c = stdscr.getch()
    
    if c == ord('q') or c == ord('Q'):
        break
    elif c == curses.KEY_UP:
        up_down(1)
    elif c == curses.KEY_DOWN:
        up_down(-1)
curses.nocbreak()
stdscr.keypad(0)
curses.echo()
curses.endwin()

РАЗОБРАЛСЯ))))
__sirroko
Доброго времени суток!

Снова возникли сложности с curses. Но на этот раз разобраться самостоятельно не получается
Строки, на которых программа завершается с ошибкой, отмечены комментариями.
Код постарался прокомментировать. Главным образом интересуют функции show_processes, up_down и последние 5 строк из __init__, т.к. баг притаился где-то там…

Ошибка: addstr() returned ERR
Код:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import curses
# import psutil # требует дополнительной установки
class stdscr:
    processes_list = ['31111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11111','11112']
    def __init__(self):        
        self.win = curses.initscr()
        curses.noecho()
        curses.cbreak()
        curses.curs_set(0) # убираем курсор
        self.win.keypad(1)
        self.win.refresh()
        curses.start_color()
        # header
        curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_BLUE)
        # processes
        # не под курсором
        curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_WHITE)
        # под курсором
        curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_BLUE)
        # menubar
        curses.init_pair(4, curses.COLOR_BLACK, curses.COLOR_BLUE)
    
        self.w_header = curses.newwin(1, curses.COLS, 0, 0)
        self.w_header.bkgd(curses.color_pair(1))
        self.w_processes = curses.newwin(curses.LINES - 2, curses.COLS, 1, 0)
        self.w_processes.bkgd(curses.color_pair(2))
        self.w_menubar = curses.newwin(1, curses.COLS, curses.LINES - 1, 0)
        self.w_menubar.bkgd(curses.color_pair(4))
        
        # корректный вывод текста на экран
        self.start_line = 0 # смещение начально строки (на случай добавления рамки)
        self.cur_index = 0 # индекс текущего элемента в списке processes_list
        # выделение области списка processes_list, которая в текущий момент выводится на экран
        self.min_index = 0
        self.max_row = curses.LINES - 2 # максимальное кол-во строк, умещающееся в текущее окно
    
    def show_header(self):
        self.w_header.clear()
        self.w_header.addstr(0, 0, 'header')
        self.w_header.refresh()
    
    def show_processes(self):
        self.w_processes.clear()
        
        # в цилке выводится только опредленная область списка (границы min_index, min_index + max_row)
        for i in range(self.min_index, self.min_index + self.max_row):
            if i == len(self.processes_list):
                break
            if i == self.cur_index:
                # ругается на эти строки
                self.win.addstr(i - self.min_index + self.max_row, 1, self.processes_list[i], curses.color_pair(2))
            else:
                # ругается на эти строки
                self.win.addstr(i - self.min_index + self.max_row, 1, self.processes_list[i])
        
        self.w_processes.refresh()
    
    def show_menubar(self):
        self.w_menubar.clear()
        self.w_menubar.addstr(0, 0, 'menubar')
        self.w_menubar.refresh()
    
    # шагательный механизм
    def up_down(self, inc):
        tmp = self.cur_index + inc # новый индекс в списке, на который мы попадаем после key_up, key_down
        if tmp >= 0 and tmp < len(self.processes_list):
            # если мы достигаем крайних элементов, выведенных на экран, то смещаем область просмотра в списке
            if tmp < (self.min_index) or tmp >= (self.min_index + self.max_row):
                self.min_index += inc
            self.cur_index = tmp
            self.show_processes()
    
    def main_loop(self):
        self.show_header()
        self.show_processes()
        self.show_menubar()
        while True:
            key = self.win.getch()
            
            if key == ord('q') or key == ord('Q'):
                break
            elif key == curses.KEY_DOWN:
                self.up_down(1)
            elif key == curses.KEY_UP:
                self.up_down(-1)
    def restore_screen(self):
        self.win.keypad(0)
        curses.nocbreak()
        curses.echo()
        curses.endwin()
class task_manager:
    def __init__(self):
        pass
    def kill_process(self):
        pass
    
    def refresh_processes(self):
        pass
    
def main():
    try:
        scr = stdscr()
        scr.main_loop()
    except Exception as err:
        scr.win.clear()
        scr.win.addstr(1, 1, str(err))
        scr.win.refresh()
        scr.win.getch()
    finally:
        scr.restore_screen()
if __name__ == '__main__':
    main()

Такой же код, только без дополнительных областей w_header и w_menubar, работает. При необходимости могу выложить…

p.s. Заранее спасибо!
p.p.s Python 3.2.3
__sirroko
Кажется, я сам с собой тут общаюсь…
Но да ладно, ошибку я все-таки нашел)

Если кому-нибудь интересно, то, на всякий случай, выкладываю код правильной функции show_processes:
    def show_processes(self):
        self.w_processes.clear()
        
        # в цилке выводится только опредленная область списка (границы min_index, min_index + max_row)
        for i in range(self.min_index, self.min_index + self.max_row):
            if i == len(self.processes_list):
                break
            if i == self.cur_index:
                # ругаЛся на эти строки # не win,  а w_processes, и + self.max_row не нужно было прибавлять
                # оно давало больше смещение, и текст писался в несуществующую строку
                self.w_processes.addstr(i - self.min_index, 1, self.processes_list[i], curses.color_pair(3))
            else:
                # ругаЛся на эти строки
                self.w_processes.addstr(i - self.min_index, 1, self.processes_list[i])
        
        self.w_processes.refresh()
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB