nodelay () вызывает завершение программы python curses

Я написал программу curses на питоне. Работает нормально. Однако, когда я использую nodelay(), программа закрывается сразу после запуска в терминале, при этом ничего не отображается (просто новое приглашение).

ИЗМЕНИТЬ

Этот код воспроизведет ошибку:

sc = curses.initscr()

sc.nodelay(1) # But removing this line allows the program to run properly

for angry in range(20):
        sc.addstr(angry, 1, "hi")

Вот мой полный код

import curses, time, sys, random

def paint(x, y, i):
        #...
def string(s, y):
        #...

def feed():
        #...

sc = curses.initscr()
curses.start_color()
curses.curs_set(0)
sc.nodelay(1) #########################################

 # vars + colors inited

for angry in range(20):
        try:
                dir = chr(sc.getch())

                sc.clear()

                feed()

                #lots of ifs

                body.append([x, y])
                body.pop(0)

                for point in body:
                        paint(*point, i=2)

                sc.move(height-1, 1)
                sc.refresh()
                time.sleep(wait)

        except Exception as e:
                print sys.exc_info()[0], e

sc.getch()
curses.beep()

curses.endwin()

Почему это происходит и как я могу безопасно использовать nodelay()?


person ACarter    schedule 22.12.2012    source источник
comment
Попробуйте сократить свой код до минимума, необходимого для воспроизведения ошибки. Например, вы можете установить nodelay (), а затем войти в бесконечный цикл, который прерывается и завершается, когда вы получаете ключ (). Если ошибка исчезнет в минимальном тестовом примере, выясните, что изменилось. Если это не поможет, опубликуйте неудачный тестовый пример.   -  person Philip    schedule 22.12.2012
comment
@Philip хорошо подумал, сделал это и опубликовал результаты.   -  person ACarter    schedule 22.12.2012


Ответы (2)


Я переписал вашу миниатюрную демонстрацию, чтобы заставить работать базовую функциональность. У него есть неблокирующий getch (). Если вы удерживаете клавишу Q при вызове getch (), программа завершается, в противном случае цикл продолжается.

import curses, time

def main(sc):
    sc.nodelay(1)

    for angry in range(20):
        sc.addstr(angry, 1, "hi")
        sc.refresh()

        if sc.getch() == ord('q'):
            break

        time.sleep(1)

if __name__=='__main__':
    curses.wrapper(main)

Самое значительное изменение, которое я сделал, - это использование curses.wrapper для получения контекст экрана вместо использования curses.initscr (). Преимущество состоит в том, что если ваша программа встречает неперехваченное исключение (например, нажатие ^ C), она отменяет все изменения, внесенные вами в терминал, например, отключение курсора перед выходом. Это очень помогает при отладке.

Отсюда я бы рекомендовал добавить функции вашей программы очень маленькими шагами. Проклятия - это своего рода боль, и если вы вносите много изменений одновременно, трудно понять, какое из них привело к поломке. Удачи!

person Philip    schedule 22.12.2012
comment
Решено. Добавление основной оболочки позволило мне увидеть, что я выхожу из-за ошибки, когда getch() ничего не вернул (поскольку вход был недоступен), и меня пытались поместить в chr(), который ничего не может обработать. Спасибо за помощь, это будет действительно полезно при устранении других ошибок. - person ACarter; 23.12.2012

Я не вижу разницы при запуске вашей небольшой тестовой программы с или без строки sc.nodelay().

Ни в том, ни в другом случае на экране ничего не выводится ...

person Roland Smith    schedule 22.12.2012
comment
Дело в том, что для меня с sc.nodelay() окна проклятия даже не открываются, и, следовательно, я ничего не могу сделать, потому что делать это не на чем. - person ACarter; 23.12.2012