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
相关产品推荐
相关产品推荐

