基于使用 PySimpleGUI 和 pyhook 的按钮按下锁定键和释放键

问题描述

我创建了一个程序,用户只能通过按下按钮退出程序才能访问系统键,例如 ctrl 和 alt。但是,当我运行该程序时,它确实卡在了 UI 中并且不允许我做任何事情。我哪里错了?提前致谢。

import PySimpleGUI as sg
import pyWinhook
import pythoncom

layout=[[sg.Button('Exit')]]
        
def blockKeys(event):
    if event.Key.lower() in ['lwin','tab','lmenu']:
        return False    # block these keys
    else:
        # return True to pass the event to other handlers
        return True

def releaseKeys(event):
    return True
        
window = sg.Window('Window Title',layout,no_titlebar=True,location=(0,0),size=(800,600),keep_on_top=True).Finalize()
window.Maximize()
hm = pyWinhook.HookManager()
hm.MouseAll = releaseKeys
hm.KeyAll = blockKeys
hm.HookMouse()
hm.HookKeyboard()
pythoncom.PumpMessages()

while True:
    event,values = window.read()
    print(event,values)
    
    if event =='Exit':
        hm = pyWinhook.HookManager()
        hm.MouseAll = releaseKeys
        hm.KeyAll = releaseKeys
        hm.HookMouse()
        hm.HookKeyboard()
        pythoncom.PumpMessages()
        break;

window.close()

解决方法

pythoncom.PumpMessages() 只是闲置等待 Windows 事件。这意味着它会一直在那里等待,什么也不做。您在 PySimpleGUI 中使用了 while 循环,因此没有必要。

代码修改如下,

import PySimpleGUI as sg
import pyWinhook
import pythoncom

layout=[[sg.Button('Exit')]]

def blockKeys(event):
    if event.Key.lower() in ['lwin','tab','lmenu']:
        return False    # block these keys
    else:
        # return True to pass the event to other handlers
        return True

def releaseKeys(event):
    return True

window = sg.Window('Window Title',layout,return_keyboard_events=True,finalize=True)
hm = pyWinhook.HookManager()
hm.MouseAll = releaseKeys
hm.KeyAll = blockKeys
hm.HookMouse()
hm.HookKeyboard()
# pythoncom.PumpMessages()

while True:
    event,values = window.read()
    print(event,values)

    if event =='Exit':
        hm = pyWinhook.HookManager()
        hm.MouseAll = releaseKeys
        hm.KeyAll = releaseKeys
        hm.HookMouse()
        hm.HookKeyboard()
        # pythoncom.PumpMessages()
        break;

window.close()