You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySimpleGUI输入框键盘输入重复问题求助(按键按下松开均触发)

解决PySimpleGUI键盘输入重复的问题

问题原因

你遇到的重复输入问题,是因为开启return_keyboard_events=True后,PySimpleGUI会在按键按下和松开两个动作时都返回事件。比如按数字1,会先后触发'1'(按下)和'1:UP'(松开)两个事件,你的代码没区分这两种事件,导致两次都执行了追加输入的操作,所以出现11这种重复内容。

修复方案1:过滤松开事件

在处理键盘事件前,先判断事件是否带有:UP后缀,只处理不带后缀的按下事件:

import PySimpleGUI as sg

layout = [
    [sg.Text('Calculator')],
    [sg.Input(size=(10,1), key='DISPLAY', justification='right')],
    [sg.Button('1'), sg.Button('2'), sg.Button('3')],
    [sg.Button('4'), sg.Button('5'), sg.Button('6')],
    [sg.Button('7'), sg.Button('8'), sg.Button('9')],
    [sg.Button('0'), sg.Button('+'), sg.Button('-')],
    [sg.Button('*'), sg.Button('/'), sg.Button('C')],
    [sg.Button('='), sg.Button('.')],
]

window = sg.Window('Calculator', layout, return_keyboard_events=True)

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

    if event == sg.WIN_CLOSED:
        break
    
    # 过滤掉按键松开的事件(带:UP后缀)
    if ':UP' in event:
        continue

    if event.isdigit() or event in ['+', '-', '*', '/']:
        current_value = values['DISPLAY']
        window['DISPLAY'].update(f'{current_value}{event}')
    
    elif event == 'C':
        window['DISPLAY'].update('')
    
    elif event == '=':
        try:
            result = eval(values['DISPLAY'])
            window['DISPLAY'].update(str(result))
        except:
            window['DISPLAY'].update('Error')

window.close()

修复方案2:使用bind绑定按键按下事件(更推荐)

return_keyboard_events是PySimpleGUI的旧特性,更规范的做法是用bind方法给窗口绑定<KeyPress>事件,这样只会在按键按下时触发:

import PySimpleGUI as sg

layout = [
    [sg.Text('Calculator')],
    [sg.Input(size=(10,1), key='DISPLAY', justification='right')],
    [sg.Button('1'), sg.Button('2'), sg.Button('3')],
    [sg.Button('4'), sg.Button('5'), sg.Button('6')],
    [sg.Button('7'), sg.Button('8'), sg.Button('9')],
    [sg.Button('0'), sg.Button('+'), sg.Button('-')],
    [sg.Button('*'), sg.Button('/'), sg.Button('C')],
    [sg.Button('='), sg.Button('.')],
]

window = sg.Window('Calculator', layout)
# 绑定按键按下事件
window.bind('<KeyPress>', '-KEYPRESS-')

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

    if event == sg.WIN_CLOSED:
        break
    
    # 处理按键按下事件
    if event.endswith('-KEYPRESS-'):
        key = event.split('-')[0]  # 获取实际按键内容
        if key.isdigit() or key in ['+', '-', '*', '/']:
            current_value = values['DISPLAY']
            window['DISPLAY'].update(f'{current_value}{key}')
    
    elif event == 'C':
        window['DISPLAY'].update('')
    
    elif event == '=':
        try:
            result = eval(values['DISPLAY'])
            window['DISPLAY'].update(str(result))
        except:
            window['DISPLAY'].update('Error')

window.close()

额外提示

  • eval函数存在安全风险,学习阶段使用没问题,但实际项目中建议用更安全的表达式解析方式。
  • 输入框默认可直接接收键盘输入,若不需要统一处理按钮和键盘逻辑,也可以去掉手动键盘事件处理,让输入框自行处理输入,也能避免重复问题。

内容的提问来源于stack exchange,提问作者sumthingranedum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 04:23:13