我正在寻找一个Python脚本,它在每个时间间隔内都会持续等待用户输入一段时间.如果用户未能在此时间范围内提供输入,脚本应自动执行预定义的操作并无限期地继续此过程.换句话说,我需要一个 routine ,它永远运行,但快速判断用户输入的任何字符.

为了实现这一点,我制作了一个代码片段,其中getch函数捕获用户输入的字符.程序在超时时间内等待用户的输入.如果用户未能在此时间间隔内提供输入,则会发出通知以指示时间已过.

import threading


def getch(input_str: list) -> None:
    """Gets a single character"""
    try:
        import msvcrt

        input_str.append(msvcrt.getch().decode("utf-8"))
    except ImportError:
        import sys
        import termios
        import tty

        fd = sys.stdin.fileno()
        oldsettings = termios.tcgetattr(fd)
        try:
            tty.setraw(fd)
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, oldsettings)
        input_str.append(ch)


def input_with_timeout(timeout):
    print("You have {} seconds to enter something:".format(timeout))
    input_str = []
    input_thread = threading.Thread(target=getch, args=(input_str,))
    input_thread.start()
    input_thread.join(timeout)

    if input_thread.is_alive():
        print("Time's up! Performing default operation.")
    else:
        print("You entered:", input_str)


while True:
    input_with_timeout(5)

当用户在分配的时间内提供输入时,系统正常工作.然而,如果时间过go 了,就会出现两个问题:第一,文本显示出现故障,导致文本放错位置;第二,用户必须多次输入他们的响应,因为一次try 似乎不能准确地记录输入.

enter image description here Because libraries such as pynput and keyboard have limitations in some environments, I cannot use them.

推荐答案

既然你很乐意使用msvcrt,那么这种最小实现有什么问题呢?

import threading
import time
import msvcrt


def periodical():
    while True:
        print("\nPrint periodic message")
        time.sleep(3)


def listen_for_keypress():
    while True:
        if msvcrt.kbhit():  
            key = msvcrt.getch()
            print(f"\nKey pressed: {key.decode('utf-8')}", end='')


if __name__ == "__main__":
    threading.Thread(target=periodical, daemon=True).start()
    listen_for_keypress()

请注意,当直接从PyCharm这样的环境运行时,这将无法正常工作,因为它的控制台实现的功能不像Windows控制台主机或Windows终端那样的标准控制台.但在这两种情况下,它似乎做了你的要求?

我的例子周期性地打印一条消息,但当然,如果你有一种方法来传达这个事实,它也可以终止:

import threading
import time
import msvcrt


def application_timeout(timeout, stop_event):
    time.sleep(timeout)
    stop_event.set()  # signal stop


def listen_for_keypress(stop_event):
    while not stop_event.is_set():
        if msvcrt.kbhit():
            key = msvcrt.getch()
            print(f"\nKey pressed: {key.decode('utf-8')}", end='')


if __name__ == "__main__":
    stop = threading.Event()
    threading.Thread(target=application_timeout, args=(3, stop), daemon=True).start()

    listen_for_keypress(stop)

Python相关问答推荐

对Numpy函数进行载体化

使用FASTCGI在IIS上运行Django频道

Python daskValue错误:无法识别的区块管理器dask -必须是以下之一:[]

如何使用matplotlib在Python中使用规范化数据和原始t测试值创建组合热图?

追溯(最近最后一次调用):文件C:\Users\Diplom/PycharmProject\Yolo01\Roboflow-4.py,第4行,在模块导入roboflow中

未删除映射表的行

如何在Windows上用Python提取名称中带有逗号的文件?

如何在Django基于类的视图中有效地使用UTE和RST HTIP方法?

计算组中唯一值的数量

优化器的运行顺序影响PyTorch中的预测

实现自定义QWidgets作为QTimeEdit的弹出窗口

当我try 在django中更新模型时,模型表单数据不可见

使用Python查找、替换和调整PDF中的图像'

如何杀死一个进程,我的Python可执行文件以sudo启动?

从列表中获取n个元素,其中list [i][0]== value''

使用Openpyxl从Excel中的折线图更改图表样式

用SymPy在Python中求解指数函数

Pandas 数据帧中的枚举,不能在枚举列上执行GROUP BY吗?

将Pandas DataFrame中的列名的长文本打断/换行为_STRING输出?

ValueError:必须在Pandas 中生成聚合值