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

PySimpleGUI拉力赛GPS应用:实现点击sg.Input控件调用自定义键盘并填充值的问题

解决PySimpleGUI触屏下自定义数字键盘填充Input控件的问题

你的核心问题在于没有让目标Input控件响应点击事件,以及未在主事件循环中正确处理这些事件来调用自定义键盘。下面是一步步的解决方案:

1. 让Input控件响应触屏/点击事件

PySimpleGUI的sg.Input默认不会在点击(或触屏触摸)时触发事件,你需要给(row, 2)和(row, 3)这两个Input控件添加enable_events=True参数,这样用户点击它们时,事件循环会接收到对应的key事件。

修改你的行布局代码:

for row in range(0, 100):
    current_row = [
        sg.Text(row),
        sg.Text(size=(10, 1), pad=(0, 0), key=(row, 1)),
        # 添加enable_events=True让控件响应点击
        sg.Input(size=(10, 1), pad=(0, 0), key=(row, 2), enable_events=True),
        sg.Input(size=(10, 1), pad=(0, 0), key=(row, 3), enable_events=True),
        sg.Text(size=(10, 1), pad=(0, 0), key=(row, 4)),
    ]

2. 在主事件循环中处理Input点击事件

接下来,你需要在主窗口的事件循环中捕获这些Input控件的事件,调用自定义键盘函数,然后将返回值填充到对应的Input中。

假设你的主窗口是window_settings,修改事件循环如下:

while True:
    event, values = window_settings.read()
    if event == sg.WIN_CLOSED:
        break
    
    # 处理(row, 2)和(row, 3)的点击事件
    if isinstance(event, tuple) and len(event) == 2:
        row_num, col_num = event
        # 判断是否是需要调用键盘的目标列
        if col_num in (2, 3):
            # 调用自定义键盘,传入当前Input的值作为初始内容(提升体验)
            input_result = keyboard(values[event])
            # 只有当用户点击Enter(而非关闭键盘窗口)时才更新控件
            if input_result is not None:
                window_settings[event].update(input_result)
    
    # 保留你原来的行数据填充逻辑
    for row in range(0, 100):
        if row < 100 and values[(row, 2)] != '':
            window_settings[(row + 1, 1)].update(values[(row, 2)])
        if values[(row, 2)] != '' and values[(row, 3)] != '' and values[(row, 2)] != '0' and values[(row, 3)] != '0':
            dataframe.loc[row, 'Fin'] = float(values[(row, 2)])
            dataframe.loc[row, 'Vitesse'] = float(values[(row, 3)])
            window_settings[(row, 4)].update(get_time(dataframe, row))

window_settings.close()

3. 优化自定义键盘(可选)

为了提升触屏操作体验,让键盘打开时自动填充当前Input的内容,用户可以直接修改而不是从头输入。修改你的keyboard函数,添加初始值参数:

def keyboard(initial_value=''):
    layout = [
        # 传入初始值到输入框
        [sg.InputText(size=(14, 1), font=("Helvetica", 20), key='input', default_text=initial_value), sg.Button('Clear', size=(5, 1), font=("Helvetica", 20))],
        [sg.Button('1', size=(5, 2), font=("Helvetica", 20)), sg.Button('2', size=(5, 2), font=("Helvetica", 20)), sg.Button('3', size=(5, 2), font=("Helvetica", 20))],
        [sg.Button('4', size=(5, 2), font=("Helvetica", 20)), sg.Button('5', size=(5, 2), font=("Helvetica", 20)), sg.Button('6', size=(5, 2), font=("Helvetica", 20))],
        [sg.Button('7', size=(5, 2), font=("Helvetica", 20)), sg.Button('8', size=(5, 2), font=("Helvetica", 20)), sg.Button('9', size=(5, 2), font=("Helvetica", 20))],
        [sg.Button('.', size=(5, 2), font=("Helvetica", 20)), sg.Button('0', size=(5, 2), font=("Helvetica", 20)), sg.Button('Enter', size=(5, 2), font=("Helvetica", 20))]
    ]
    window = sg.Window('Keyboard', layout)
    while True:
        event, values = window.read(timeout=100)
        if event == sg.WIN_CLOSED:
            window.close()
            return None  # 关闭窗口时返回None,避免更新空值
        if event == sg.TIMEOUT_KEY:
            continue
        if event == 'Enter':
            window.close()
            return values['input']
        if event == 'Clear':
            window['input'].update('')
        else:
            window['input'].update(values['input'] + event)

为什么之前的尝试没成功?

你之前的代码没有给Input控件添加enable_events=True,导致点击这些控件时不会触发事件循环中的事件,自然无法调用键盘函数。加上这个参数后,事件循环就能捕获到点击动作,进而执行后续的键盘调用和值填充逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:29:05