Избегать raw_input для нажатия клавиш во время цикла для окон - PullRequest
3 голосов
/ 21 декабря 2011

Я пытаюсь создать программу, имеющую raw_input в цикле, если кто-то нажимает клавишу во время выполнения длинного цикла, следующий raw_input принимает это в качестве ввода, как мне избежать этого?

Я не знаю, что еще добавить к этому простому вопросу. Дайте мне знать, если потребуется больше.

EDIT

Какой-то код

for i in range(1000):
  var = raw_input("Enter the number")
  #.... do some long magic and stuff here which takes afew seconds
  print 'Output is'+str(output)

Так что, если кто-то что-то нажимает внутри магической фазы, это будет входом для следующего цикла. Вот где начинается проблема. (И да, цикл должен работать 1000 раз).

Ответы [ 3 ]

3 голосов
/ 21 декабря 2011

Это работает для меня с Windows 7 64bit, python 2.7.

import msvcrt

def flush_input():
  while msvcrt.kbhit():
    msvcrt.getch()
1 голос
/ 21 декабря 2011

Просто соберите свой ввод за пределами цикла (перед тем, как войти в цикл). Вы действительно хотите, чтобы пользователь ввел 1000 номеров? ну, может быть, вы делаете. но просто включите цикл вверху, соберите 1000 чисел в начале и сохраните их в массиве.

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

как то так:

    def getvars(top=1000):
        vars = []
        for i in range(0,top):
            anum = int(raw_input('%d) Please enter another number: ' % i))
            vars.append(anum) 
        return vars

    def doMagic(numbers):
        top = len(numbers)
        for number in numbers: 
            # do magic number stuff
            print 'this was my raw number %s' % number

    if __name__ == "__main__":
        numbers = getvars(top=10)
        doMagic(numbers)

представлен другим способом и менее зависим от ОС

Есть еще один способ сделать это, который должен работать. У меня нет окна, удобного для тестирования, но я использовал этот прием и довольно недокументирован. Возможно, я выдаю секреты ... но это в основном так: обманом заставьте думать, что ваше приложение является заставкой, вызывая API, который включает функцию заставки в начале ваших магических вычислений. в конце ваших волшебных вычислений или когда вы снова готовы принять ввод, снова вызовите API и отключите функцию заставки.

Это бы сработало.

Есть и другой способ сделать это. Поскольку вы находитесь в Windows, это тоже будет работать. но это изрядное количество работы, но не слишком много. В окнах окно, находящееся на переднем плане (вверху Z-порядка), это окно получает «необработанный поток ввода». Необработанный поток ввода получает ввод от мыши и клавиатуры. Таким образом, чтобы захватить все входные данные, все, что вам нужно сделать, - это создать функцию, которая стоит в прозрачном или (непрозрачном) окне, которое находится в верхней части Z-последовательности. SetWindowPos сделает свое дело, охватит весь экран и, возможно, отобразит сообщение, такое как Эвен Гедульд когда вы готовы запросить у пользователя дополнительные данные, вы используете showwindow (), чтобы скрыть окно, показать предыдущие результаты, получить ввод, а затем заново отобразить окно и снова захватить клавиши / мышь.

Конечно, все эти решения привязывают вас к конкретной ОС, если вы не реализуете какую-то попытку / исключая обработку и / или перенос низкоуровневых вызовов Windows SDK.

1 голос
/ 21 декабря 2011

Я поставил ОС в заголовке, окно 7 64 битное, если быть точным.Я видел ответы там.Они действительно применяются, но, черт возьми, они такие большие.Разве нет других дружественных и более безопасных способов получения входных данных?

Позвольте мне объяснить, почему вам нужен такой сложный процесс.Когда вы нажимаете клавишу, она сохраняется в разделе памяти компьютера, который называется буфером клавиатуры (не путать с буфером stdin).Этот буфер хранит нажатие клавиши до тех пор, пока она не будет обработана вашей программой.Python не предоставляет никакой независимой от платформы обертки для выполнения этой задачи.Вы должны полагаться на системные системные вызовы, чтобы получить доступ к этому буферу и очистить его, прочитать или запросить его.msvcrt - это библиотека времени выполнения MS VC ++, а python msvcrt предоставляет оболочку для нее.Если вы не хотите решения, независимого от платформы, оно довольно простое.

Используйте msvcrt getch для чтения символа с консоли.msvcrt.kbhit() для проверки наличия нажатия клавиши в буфере клавиатуры и т. Д.Итак, как показал МэттХ, это всего лишь пара строк кода.И если вы думаете, что вы новичок, воспользуйтесь этой возможностью, чтобы узнать что-то новое.

...