这是我第一次做Python程序,我做了一个简单的Python程序,如下所示,但它在键盘点处冻结.is_Press()调用,它无法打印我的测试消息"Loop 1 time now",这意味着按下任何键都不会给出任何响应,这个函数调用根本不会返回,甚至Ctrl-C都不能中断程序并返回命令提示符控制.

import threading
import asyncio
import time
import keyboard

flagkeypress = False
keycode = 'a'
flagserverconnected = False

def task1():
    print("Connecting to server")
    asyncio.run(connect2svr())
    print("task1 ended")


async def connect2svr():
    global flagkeypress
    global keycode
    global flagserverconnected

    try:
        print("Connected to server")
        flagserverconnected = True

        keeploopBLE = True
        while keeploopBLE:
            if flagkeypress == True:
                flagkeypress = False
                if keycode == 'q':
                    for k in range(14, 19):
                        sk="##SP"+ f"{k:02}"
                        print(sk)
                        await asyncio.sleep(1)
                if keycode == ']':
                    keeploopBLE = False
    except Exception as e:
        print(f"Error: {e}")


print("Start of my main program")
# Create threads
t1 = threading.Thread(target=task1)
# Start threads
t1.start()

keeploop = True
while keeploop:
    print("\nOptions: [Q]=Get Version, [T]=Get Time, [P]=Start/End Get GPS Time\n")
    print("Press key for command:")

    waitkey = True
    while waitkey:
        if keyboard.is_pressed('t'):
            my_kevent = keyboard.read_event()
            keyn = my_kevent.name
            print(f"key {keyn} is pressed, program going to end")
            keycode = ']'
            flagkeypress = True
            waitkey = False
            keeploop = False
        elif keyboard.is_pressed('q'):
            my_kevent = keyboard.read_event()
            keyn = my_kevent.name
            print(f"key {keyn} is pressed")
            keycode = 'q'
            flagkeypress = True
            waitkey = False
        print("loop 1 time now")
        time.sleep(0.2)

    time.sleep(0.5)
print("Main program ended")
t1.join()

如果我删除了task1线程,则Python代码简化如下,然后它就会像我预期的那样工作,"loop 1 time now"被连续打印出来.线程task1的存在影响键盘模块API不工作的根本原因是什么?但到目前为止,我不能100%地说冻结是由线程task1的存在引起的,因为我在task1存在之前有另一个版本,如果我删除一个Waiting While循环,它仍然可以工作,但在我进一步将其简化为这两个版本之前,我没有保存那个版本.

import asyncio
import time
import keyboard

flagkeypress = False
keycode = 'a'

print("Start of my main program")
keeploop = True
while keeploop:

    print("\nOptions: [Q]=Get Version, [T]=Get Time, [P]=Start/End Get GPS Time\n")
    print("Press key for command:")

    waitkey = True
    while waitkey:
        if keyboard.is_pressed('t'):
            my_kevent = keyboard.read_event()
            keyn = my_kevent.name
            print(f"key {keyn} is pressed, program going to end")
            keycode = ']'
            flagkeypress = True
            waitkey = False
            keeploop = False
        elif keyboard.is_pressed('q'):
            my_kevent = keyboard.read_event()
            keyn = my_kevent.name
            print(f"key {keyn} is pressed")
            keycode = 'q'
            flagkeypress = True
            waitkey = False
        print("loop 1 time now")
        time.sleep(0.2)

    time.sleep(0.5)
print("Main program ended")

输出:

C:\Projects\pytest1>python pytest3.py
Start of my main program

Options: [Q]=Get Version, [T]=Get Time, [P]=Start/End Get GPS Time

Press key for command:
loop 1 time now
loop 1 time now
loop 1 time now
loop 1 time now
key q is pressed
loop 1 time now

Options: [Q]=Get Version, [T]=Get Time, [P]=Start/End Get GPS Time

Press key for command:
loop 1 time now
loop 1 time now
loop 1 time now
loop 1 time now
loop 1 time now
key q is pressed
loop 1 time now

Options: [Q]=Get Version, [T]=Get Time, [P]=Start/End Get GPS Time

Press key for command:
loop 1 time now
loop 1 time now
key q is pressed
loop 1 time now

Options: [Q]=Get Version, [T]=Get Time, [P]=Start/End Get GPS Time

Press key for command:
loop 1 time now
loop 1 time now
key q is pressed
loop 1 time now

Options: [Q]=Get Version, [T]=Get Time, [P]=Start/End Get GPS Time

Press key for command:
loop 1 time now
loop 1 time now
loop 1 time now
key q is pressed
loop 1 time now

Options: [Q]=Get Version, [T]=Get Time, [P]=Start/End Get GPS Time

Press key for command:
loop 1 time now
loop 1 time now
loop 1 time now
loop 1 time now
loop 1 time now
key q is pressed
loop 1 time now

Options: [Q]=Get Version, [T]=Get Time, [P]=Start/End Get GPS Time

Press key for command:
loop 1 time now
loop 1 time now
loop 1 time now
loop 1 time now
loop 1 time now
key t is pressed, program going to end
loop 1 time now
Main program ended

推荐答案

我已经使用带有回调函数的keyboard.add_hotkey()对其进行了测试.它可以工作,不会像keyboard.is_pressed()那样冻结.我还测试了read_key()read_event(),它们也表现出冻结和不返回的行为.无论如何,只有add_hotkey()人在工作.

add_hotkey()并不像我预期的那样有效.键缓冲区输入未被清除,并且无法在键盘模块API中清除它.当我的程序结束或调用input()时,那些按下的键将弹出.所以这绝对不能满足我的基本要求.

我试了另一个模块--pynput.此模块也没有冻结/不返回问题;但是,它也存在无法清除按键输入的问题.当我的程序结束时,所有按下的键都会弹出.

最后,我try 了msvcrt模块(微软).msvcrt.kbhit()msvcrt.getch()在c语言中工作得很好.因此,msvcrt模块完美地满足了我的要求,并且能够很好地与多线程和线程中的异步函数一起工作.

我的结论是,msvcrt的key API是最稳定和没有错误的;其他的将缺乏密钥缓冲区清除能力,这是一个很大的缺陷.当然,最大的缺陷是键盘模块,它充满了错误.

Python相关问答推荐

try 与gemini-pro进行多轮聊天时出错

Matlab中是否有Python的f-字符串等效物

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

使用groupby Pandas的一些操作

OR—Tools CP SAT条件约束

如何从数据库上传数据到html?

给定高度约束的旋转角解析求解

未知依赖项pin—1阻止conda安装""

Python列表不会在条件while循环中正确随机化'

在Python 3中,如何让客户端打开一个套接字到服务器,发送一行JSON编码的数据,读回一行JSON编码的数据,然后继续?

在matplotlib中删除子图之间的间隙_mosaic

OpenGL仅渲染第二个三角形,第一个三角形不可见

Django Table—如果项目是唯一的,则单行

如何在一组行中找到循环?

仅使用预先计算的排序获取排序元素

Pandas:将值从一列移动到适当的列

PYTHON中的selenium不会打开 chromium URL

如果列包含空值,则PANAS查询不起作用

关于数字S种子序列内部工作原理的困惑

是否将列表分割为2?