web-dev-qa-db-fra.com

raw_input et timeout

Je veux faire une raw_input('Enter something: .'). Je veux qu'il reste en veille pendant 3 secondes et s'il n'y a pas d'entrée, annulez l'invite et exécutez le reste du code. Ensuite, le code boucle et implémente le raw_input encore. Je veux aussi qu'il se casse si l'utilisateur entre quelque chose comme "q".

35
ykmizu

Il existe une solution simple qui n'utilise pas de threads (du moins pas explicitement): utilisez select pour savoir quand il y a quelque chose à lire depuis stdin:

import sys
from select import select

timeout = 10
print "Enter something:",
rlist, _, _ = select([sys.stdin], [], [], timeout)
if rlist:
    s = sys.stdin.readline()
    print s
else:
    print "No input. Moving on..."

Edit [0]: apparemment ceci ne fonctionnera pas sous Windows , car l'implémentation sous-jacente de select () nécessite un socket, et sys.stdin ne l'est pas. Merci pour l'avertissement, @Fookatchu.

54
rbp

Si vous travaillez sous Windows, vous pouvez essayer ce qui suit:

import sys, time, msvcrt

def readInput( caption, default, timeout = 5):
    start_time = time.time()
    sys.stdout.write('%s(%s):'%(caption, default));
    input = ''
    while True:
        if msvcrt.kbhit():
            chr = msvcrt.getche()
            if ord(chr) == 13: # enter_key
                break
            Elif ord(chr) >= 32: #space_char
                input += chr
        if len(input) == 0 and (time.time() - start_time) > timeout:
            break

    print ''  # needed to move to next line
    if len(input) > 0:
        return input
    else:
        return default

# and some examples of usage
ans = readInput('Please type a name', 'john') 
print 'The name is %s' % ans
ans = readInput('Please enter a number', 10 ) 
print 'The number is %s' % ans 
13
Paul

J'ai du code qui crée une application de compte à rebours avec une boîte de saisie et un bouton tkinter afin qu'ils puissent entrer quelque chose et appuyer sur le bouton, si le temporisateur s'épuise, la fenêtre tkinter se ferme et leur dit qu'ils ont manqué de temps. Je pense que la plupart des autres solutions à ce problème n'ont pas de fenêtre qui apparaît, alors j'ai pensé ajouter à la liste :)

avec raw_input () ou input (), ce n'est pas possible car il s'arrête à la section d'entrée, jusqu'à ce qu'il reçoive l'entrée, puis il continue ...

J'ai pris du code à partir du lien suivant: Faire un compte à rebours avec Python et Tkinter?

J'ai utilisé la réponse de Brian Oakley à ce problème et ajouté la boîte de saisie, etc.

import tkinter as tk

class ExampleApp(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)
        def well():
            whatis = entrybox.get()
            if whatis == "": # Here you can check for what the input should be, e.g. letters only etc.
                print ("You didn't enter anything...")
            else:
                print ("AWESOME WORK DUDE")
            app.destroy()
        global label2
        label2 = tk.Button(text = "quick, enter something and click here (the countdown timer is below)", command = well)
        label2.pack()
        entrybox = tk.Entry()
        entrybox.pack()
        self.label = tk.Label(self, text="", width=10)
        self.label.pack()
        self.remaining = 0
        self.countdown(10)

    def countdown(self, remaining = None):
        if remaining is not None:
            self.remaining = remaining

        if self.remaining <= 0:
            app.destroy()
            print ("OUT OF TIME")


        else:
            self.label.configure(text="%d" % self.remaining)
            self.remaining = self.remaining - 1
            self.after(1000, self.countdown)

if __name__ == "__main__":
    app = ExampleApp()
    app.mainloop()

Je sais que ce que j'ai ajouté était un peu paresseux mais ça marche et c'est un exemple seulement

Ce code fonctionne pour Windows avec Pyscripter 3.3

2
W1ll1amvl

Pour la réponse de rbp:

Pour tenir compte d'une entrée égale à un retour chariot, ajoutez simplement une condition imbriquée:

if rlist:
    s = sys.stdin.readline()
    print s
    if s == '':
        s = pycreatordefaultvalue
1
maphilli14