Python 等待 x 秒等待某个键,如果没有按下则继续执行

发布于 2024-11-10 09:18:01 字数 128 浏览 4 评论 0原文

我正在寻找执行以下操作的代码片段/示例:

  • 显示一条消息,例如“按任意键进行配置或等待 X 秒继续”
  • 等待,例如 5 秒并继续执行,或输入 configure() 子例程如果按下某个键。

I'm looking for a code snippet/sample which performs the following:

  • Display a message like "Press any key to configure or wait X seconds to continue"
  • Wait, for example, 5 seconds and continue execution, or enter a configure() subroutine if a key is pressed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

孤独患者 2024-11-17 09:18:01

如果您使用的是 Unix/Linux,那么 select 模块将为您提供帮助。

import sys
from select import select

print "Press any key to configure or wait 5 seconds..."
timeout = 5
rlist, wlist, xlist = select([sys.stdin], [], [], timeout)

if rlist:
    print "Config selected..."
else:
    print "Timed out..."

如果您使用的是 Windows,请查看 msvcrt 模块。 (请注意,这在 IDLE 中不起作用,但在 cmd 提示符下有效)

import sys, time, msvcrt

timeout = 5
startTime = time.time()
inp = None

print "Press any key to configure or wait 5 seconds... "
while True:
    if msvcrt.kbhit():
        inp = msvcrt.getch()
        break
    elif time.time() - startTime > timeout:
        break

if inp:
    print "Config selected..."
else:
    print "Timed out..."

If you're on Unix/Linux then the select module will help you.

import sys
from select import select

print "Press any key to configure or wait 5 seconds..."
timeout = 5
rlist, wlist, xlist = select([sys.stdin], [], [], timeout)

if rlist:
    print "Config selected..."
else:
    print "Timed out..."

If you're on Windows, then look into the msvcrt module. (Note this doesn't work in IDLE, but will in cmd prompt)

import sys, time, msvcrt

timeout = 5
startTime = time.time()
inp = None

print "Press any key to configure or wait 5 seconds... "
while True:
    if msvcrt.kbhit():
        inp = msvcrt.getch()
        break
    elif time.time() - startTime > timeout:
        break

if inp:
    print "Config selected..."
else:
    print "Timed out..."
咽泪装欢 2024-11-17 09:18:01

Python 没有任何标准方法来捕获此问题,它只能通过 input() 和 raw_input() 获取键盘输入。

如果你真的想要这个,你可以使用 Tkinter 或 pygame 将击键捕获为“事件”。还有一些特定于平台的解决方案,例如 pyHook。但如果它对你的程序不是绝对重要,我建议你让它以另一种方式工作。

Python doesn't have any standard way to catch this, it gets keyboard input only through input() and raw_input().

If you really want this you could use Tkinter or pygame to catch the keystrokes as "events". There are also some platform-specific solutions like pyHook. But if it's not absolutely vital to your program, I suggest you make it work another way.

童话里做英雄 2024-11-17 09:18:01

如果将 time.sleep、threading.Thread 和 sys.stdin.read 结合起来,您可以轻松等待指定的输入时间,然后继续。

t = threading.Thread(target=sys.stdin.read(1) args=(1,))
t.start()
time.sleep(5)
t.join()

If you combine time.sleep, threading.Thread, and sys.stdin.read you can easily wait for a specified amount of time for input and then continue.

t = threading.Thread(target=sys.stdin.read(1) args=(1,))
t.start()
time.sleep(5)
t.join()
伪心 2024-11-17 09:18:01

我是这样做的:

import threading
import time
import sys


class MyThread(threading.Thread):
    def __init__(self, threadID, name, counter, f):
        super().__init__()
        self.threadID = threadID
        self.name = name
        self.counter = counter
        self.func = f

    def run(self):
        self.func()

class KeyboardMonitor:
    def __init__(self):
        # Setting a boolean flag is atomic in Python.
        # It's hard to imagine a boolean being 
        # anything else, with or without the GIL.
        # If inter-thread communication is anything more complicated than
        # a couple of flags, you should replace low level variables with 
        # a thread safe buffer.
        self.keepGoing = True

    def wait4KeyEntry(self):
        while self.keepGoing:
            s = input("Type q to quit: ")
            if s == "q":
                self.keepGoing = False

    def mainThread(self, f, *args, **kwargs):
        """Pass in some main function you want to run, and this will run it
        until keepGoing = False. The first argument of function f must be 
        this class, so that that function can check the keepGoing flag and 
        quit when keepGoing is false."""
        keyboardThread = MyThread(1, "keyboard_thread", 0, self.wait4KeyEntry)
        keyboardThread.start()
        while self.keepGoing:
            f(self, *args, **kwargs)

def main(keyMonitorInst, *args, **kwargs):
    while keyMonitorInst.keepGoing:
        print("Running again...")
        time.sleep(1)

if __name__ == "__main__":
    uut = KeyboardMonitor()
    uut.mainThread(main)

我的方法不是让阻塞调用超时,而是启动一个线程等待用户输入输入,而另一个线程则执行其他操作。这两个进程通过少量原子操作进行通信:在本例中,设置一个布尔标志。对于比原子操作更复杂的事情,显然您应该用某种线程安全缓冲区替换原子变量。

Here's how I did it:

import threading
import time
import sys


class MyThread(threading.Thread):
    def __init__(self, threadID, name, counter, f):
        super().__init__()
        self.threadID = threadID
        self.name = name
        self.counter = counter
        self.func = f

    def run(self):
        self.func()

class KeyboardMonitor:
    def __init__(self):
        # Setting a boolean flag is atomic in Python.
        # It's hard to imagine a boolean being 
        # anything else, with or without the GIL.
        # If inter-thread communication is anything more complicated than
        # a couple of flags, you should replace low level variables with 
        # a thread safe buffer.
        self.keepGoing = True

    def wait4KeyEntry(self):
        while self.keepGoing:
            s = input("Type q to quit: ")
            if s == "q":
                self.keepGoing = False

    def mainThread(self, f, *args, **kwargs):
        """Pass in some main function you want to run, and this will run it
        until keepGoing = False. The first argument of function f must be 
        this class, so that that function can check the keepGoing flag and 
        quit when keepGoing is false."""
        keyboardThread = MyThread(1, "keyboard_thread", 0, self.wait4KeyEntry)
        keyboardThread.start()
        while self.keepGoing:
            f(self, *args, **kwargs)

def main(keyMonitorInst, *args, **kwargs):
    while keyMonitorInst.keepGoing:
        print("Running again...")
        time.sleep(1)

if __name__ == "__main__":
    uut = KeyboardMonitor()
    uut.mainThread(main)

Rather than make a blocking call time out, my approach is to start a thread that waits for the user to enter input, while another thread does something else. The two processes communicate through a small number of atomic operations: in this case, setting a boolean flag. For anything more complicated than atomic operations, obviously you should replace the atomic variable with a threadsafe buffer of some kind.

故事灯 2024-11-17 09:18:01

基于 https://note.nkmk.me/en/python-while 的想法-usage/,以及来自其他地方的。

如果 5 秒内按下 CTRL-C,程序将停止,否则将继续。

适用于 Python 3,不需要任何外部(pip install ...)库。

应该可以在 Linux 和 Windows 上运行。

如果您希望程序更频繁地检查用户输入,请在 time.sleep() 之前注释 print 函数,并将 time.sleep(1) 更改为 time.sleep(0.1)。您可能也会使用顶部打印功能。

import time

def fn_wait_for_user_input(seconds_to_wait,message):
    #print('waiting for',seconds_to_wait, 'seconds ...' )
    print (message, seconds_to_wait)
    start_time = time.time()
    try:
        while (time.time() - start_time ) < seconds_to_wait:
            '''
            parenthesis, from inside out:
            time.time() which is current time    - start time, if it is more than 10 seconds, time's up :)
            int ; so we don't count 10 -1,02=8; instead we will count 10-1 = 9, meaning 9 seconds remaining, not 8
            seconds to wait - everything else ; so we get reverse count from 10 to 1, not from 1 to 10
            '''
            print("%d" %  (  seconds_to_wait -   int(  (time.time() - start_time )   )    )    ) 
            time.sleep(1)
        print('No keypress detected.')
        return 1 #no interrupt after x seconds
    except KeyboardInterrupt:
        print('Keypress detected - exiting.')
        return 0 #interrupted
        
    


if fn_wait_for_user_input(5, "program will continue if you don't press CTRL-C within seconds:" )  == 1:
    print('continuing ....')
else:
    print('not continuing.')



注意:

使用它在一行中打印所有内容:

print("%d" %  (  seconds_to_wait -   int(  (time.time() - start_time )   )    ), end=' ', flush=True   ) #needs flush inside loop...buffered

使用它在函数内继续:

if fn_wait_for_user_input(5, "program will continue if you don't press CTRL-C within seconds:" )  == 1:
    #print('continuing ....')
    pass
else:
    #print('not continuing.')
    #exit function
    return

Based on idea from https://note.nkmk.me/en/python-while-usage/, and from elsewhere.

Program will stop if CTRL-C is pressed withing 5 seconds, otherwise will continue.

Works on Python 3, does not need any external (pip install ...) libraries.

Should work on Linux and Windows.

If you wish for program to check user input more often, comment print function before time.sleep(), and change time.sleep(1) to time.sleep(0.1). You would probably use top print function, too.

import time

def fn_wait_for_user_input(seconds_to_wait,message):
    #print('waiting for',seconds_to_wait, 'seconds ...' )
    print (message, seconds_to_wait)
    start_time = time.time()
    try:
        while (time.time() - start_time ) < seconds_to_wait:
            '''
            parenthesis, from inside out:
            time.time() which is current time    - start time, if it is more than 10 seconds, time's up :)
            int ; so we don't count 10 -1,02=8; instead we will count 10-1 = 9, meaning 9 seconds remaining, not 8
            seconds to wait - everything else ; so we get reverse count from 10 to 1, not from 1 to 10
            '''
            print("%d" %  (  seconds_to_wait -   int(  (time.time() - start_time )   )    )    ) 
            time.sleep(1)
        print('No keypress detected.')
        return 1 #no interrupt after x seconds
    except KeyboardInterrupt:
        print('Keypress detected - exiting.')
        return 0 #interrupted
        
    


if fn_wait_for_user_input(5, "program will continue if you don't press CTRL-C within seconds:" )  == 1:
    print('continuing ....')
else:
    print('not continuing.')



note:

use this to print all in one line:

print("%d" %  (  seconds_to_wait -   int(  (time.time() - start_time )   )    ), end=' ', flush=True   ) #needs flush inside loop...buffered

use this to continue inside a function:

if fn_wait_for_user_input(5, "program will continue if you don't press CTRL-C within seconds:" )  == 1:
    #print('continuing ....')
    pass
else:
    #print('not continuing.')
    #exit function
    return

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文