Frage

Diese Frage bereits eine Antwort hier:

in Python, ist es eine Möglichkeit zu, während für eine Benutzereingabe wartet, zählen Zeit, so dass nach dem, sagen wir 30 Sekunden wird die raw_input() Funktion automatisch übersprungen?

War es hilfreich?

Lösung

Die signal.alarm Funktion, auf dem @ jer empfohlenen Lösung basiert, ist leider Unix-only. Wenn Sie eine plattformübergreifende oder Windows-spezifische Lösung benötigen, können Sie es auf Basis threading.Timer stattdessen mit thread.interrupt_main eine KeyboardInterrupt an den Haupt-Thread aus dem Zeitgeber-Thread zu senden. Das heißt:.

import thread
import threading

def raw_input_with_timeout(prompt, timeout=30.0):
    print prompt,    
    timer = threading.Timer(timeout, thread.interrupt_main)
    astring = None
    try:
        timer.start()
        astring = raw_input(prompt)
    except KeyboardInterrupt:
        pass
    timer.cancel()
    return astring

Dies wird return None, ob die 30 Sekunden Zeit oder der Benutzer entscheidet, explizit auf die Treffersteuer-C bei der Eingabe auf nichts zu verzichten, aber es scheint OK, um die beiden Fälle in gleicher Weise zu behandeln (wenn Sie brauchen, um zu unterscheiden, Sie könnten für die Timer-Funktion Ihrer eigenen verwenden, die vor dem Haupt-Thread, Aufzeichnungen irgendwo die Tatsache zu unterbrechen, dass ein Timeout hat passiert ist, und in Ihrem Handler für KeyboardInterrupt Zugriff dass „irgendwo“ zu unterscheiden, die die beiden Fälle aufgetreten ist).

Bearbeiten : Ich diese Arbeit war hätte schwören können, aber ich muss falsch gewesen - der Code oben lässt die offensichtlich notwendige timer.start(), und auch damit kann ich ‚t macht es nicht mehr arbeiten. select.select wäre die offensichtliche andere Sache, um zu versuchen, aber es wird nicht die Arbeit an einer „normalen Datei“ (einschließlich stdin) in Windows -. in Unix für alle Dateien arbeitet, in Windows, nur an Steckdosen

Also ich weiß nicht, wie eine Cross-Plattform „raw Eingang mit timeout“ zu tun. Ein Windows-spezifisch man kann mit einem engen Schleife Polling msvcrt konstruiert werden. kbhit , Durchführen einer msvcrt.getche (und prüfen, ob es sich um eine Rückkehr ist die Ausgabe, um anzuzeigen, fertig ist, in diesem Fall ist es der Schleife ausbricht, sammelt sich sonst und hält zu warten) und die Zeit zu Zeit überprüft, wenn nötig. Ich kann nicht testen, weil ich keinen Windows-Rechner haben (sie sind alle Macs und Linux sind), aber hier die ungetesteten Code Ich würde vorschlagen:

import msvcrt
import time

def raw_input_with_timeout(prompt, timeout=30.0):
    print prompt,    
    finishat = time.time() + timeout
    result = []
    while True:
        if msvcrt.kbhit():
            result.append(msvcrt.getche())
            if result[-1] == '\r':   # or \n, whatever Win returns;-)
                return ''.join(result)
            time.sleep(0.1)          # just to yield to other processes/threads
        else:
            if time.time() > finishat:
                return None

Die OP in einem Kommentar, sagt er nicht zu return None auf Timeout will, aber was ist die Alternative? Die Anhebung eine Ausnahme? Rückgabe eines anderen Standardwert? Was auch immer er will Alternative er es klar anstelle meines return None setzen kann; -).

Wenn Sie nicht möchten, dass zu der Zeit nur, weil der Benutzer der Eingabe langsam (im Gegensatz zu, Schreiben nicht an alle! -), könnten Sie finishat nach jeder erfolgreichen Zeicheneingabe neu berechnen <. / p>

Andere Tipps

fand ich eine Lösung für dieses Problem in einem Blog Post . Hier ist der Code aus dieser Blog-Post:

import signal

class AlarmException(Exception):
    pass

def alarmHandler(signum, frame):
    raise AlarmException

def nonBlockingRawInput(prompt='', timeout=20):
    signal.signal(signal.SIGALRM, alarmHandler)
    signal.alarm(timeout)
    try:
        text = raw_input(prompt)
        signal.alarm(0)
        return text
    except AlarmException:
        print '\nPrompt timeout. Continuing...'
    signal.signal(signal.SIGALRM, signal.SIG_IGN)
    return ''

Bitte beachten Sie:. Dieser Code funktioniert nur auf * nix OSs

from threading import Timer


def input_with_timeout(x):    

def time_up():
    answer= None
    print 'time up...'

t = Timer(x,time_up) # x is amount of time in seconds
t.start()
try:
    answer = input("enter answer : ")
except Exception:
    print 'pass\n'
    answer = None

if answer != True:   # it means if variable have somthing 
    t.cancel()       # time_up will not execute(so, no skip)

input_with_timeout(5) # try this for five seconds

Wie es sich von selbst definiert ist ... führen Sie es in Befehlszeile, ich hoffe, Sie die Antwort bekommen Lesen Sie diese Python doc Kristall wird klar sein, was in dieser gerade passiert Code !!

Der Eingang () Funktion ist für den Benutzer warten, etwas zu geben (zumindest die [Enter] -Taste).

Wenn Sie nicht tot Set Verwendung Eingang () sind, ist unten eine viel leichtere Lösung tkinter verwenden. In tkinter können Dialogfelder (und jedes Widget) nach einer bestimmten Zeit zerstört werden.

Hier ist ein Beispiel:

import tkinter as tk

def W_Input (label='Input dialog box', timeout=5000):
    w = tk.Tk()
    w.title(label)
    W_Input.data=''
    wFrame = tk.Frame(w, background="light yellow", padx=20, pady=20)
    wFrame.pack()
    wEntryBox = tk.Entry(wFrame, background="white", width=100)
    wEntryBox.focus_force()
    wEntryBox.pack()

    def fin():
        W_Input.data = str(wEntryBox.get())
        w.destroy()
    wSubmitButton = tk.Button(w, text='OK', command=fin, default='active')
    wSubmitButton.pack()

# --- optionnal extra code in order to have a stroke on "Return" equivalent to a mouse click on the OK button
    def fin_R(event):  fin()
    w.bind("<Return>", fin_R)
# --- END extra code --- 

    w.after(timeout, w.destroy) # This is the KEY INSTRUCTION that destroys the dialog box after the given timeout in millisecondsd
    w.mainloop()

W_Input() # can be called with 2 parameter, the window title (string), and the timeout duration in miliseconds

if W_Input.data : print('\nYou entered this : ', W_Input.data, end=2*'\n')

else : print('\nNothing was entered \n')

Ein Fluch Beispiel, die für einen zeitlich Mathe-Test nimmt

#!/usr/bin/env python3

import curses
import curses.ascii
import time

#stdscr = curses.initscr() - Using curses.wrapper instead
def main(stdscr):
    hd = 100 #Timeout in tenths of a second
    answer = ''

    stdscr.addstr('5+3=') #Your prompt text

    s = time.time() #Timing function to show that solution is working properly

    while True:
        #curses.echo(False)
        curses.halfdelay(hd)
        start = time.time()
        c = stdscr.getch()
        if c == curses.ascii.NL: #Enter Press
            break
        elif c == -1: #Return on timer complete
            break
        elif c == curses.ascii.DEL: #Backspace key for corrections. Could add additional hooks for cursor movement
            answer = answer[:-1]
            y, x = curses.getsyx()
            stdscr.delch(y, x-1)
        elif curses.ascii.isdigit(c): #Filter because I only wanted digits accepted
            answer += chr(c)
            stdscr.addstr(chr(c))
        hd -= int((time.time() - start) * 10) #Sets the new time on getch based on the time already used

    stdscr.addstr('\n')

    stdscr.addstr('Elapsed Time: %i\n'%(time.time() - s))
    stdscr.addstr('This is the answer: %s\n'%answer)
    #stdscr.refresh() ##implied with the call to getch
    stdscr.addstr('Press any key to exit...')
curses.wrapper(main)

unter Linux könnte man Flüche und getch Funktion, seine nicht blockierende verwenden. siehe getch ()

https://docs.python.org/2/library/curses.html

Funktion, die darauf wartet, Tastatureingabe für x Sekunden (Sie müssen zuerst eine Flüche Fenster (win1) initialisiert werden!

import time

def tastaturabfrage():

    inittime = int(time.time()) # time now
    waitingtime = 2.00          # time to wait in seconds

    while inittime+waitingtime>int(time.time()):

        key = win1.getch()      #check if keyboard entry or screen resize

        if key == curses.KEY_RESIZE:
            empty()
            resize()
            key=0
        if key == 118:
            p(4,'KEY V Pressed')
            yourfunction();
        if key == 107:
            p(4,'KEY K Pressed')
            yourfunction();
        if key == 99:
            p(4,'KEY c Pressed')
            yourfunction();
        if key == 120:
            p(4,'KEY x Pressed')
            yourfunction();

        else:
            yourfunction

        key=0
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top