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

PySimpleGUI中InputText更新后values字典未同步的原因排查

PySimpleGUI中values字典未同步更新的问题分析与解决

问题描述

我用PySimpleGUI写了一段代码,需求是当B1、B2两个输入框有内容时,禁用并清空A1、A2输入框。GUI界面显示正常,但print(values)输出的字典没同步更新:依次给A1、A2、B1、B2输入1、2、3、4时,第三次输出的values里A1、A2还保留着原来的值,不是预期的空值。

代码示例

import PySimpleGUI as sg


def gen_layout() -> list:
    layout=[
    [sg.Text('A1', size=(20, 1)), sg.InputText(key='-INPUT-A1-', enable_events=True)],
    [sg.Text('A2', size=(20, 1)), sg.InputText(key='-INPUT-A2-', enable_events=True)],
    [sg.Text('B1', size=(20, 1)), sg.InputText(key='-INPUT-B1-', enable_events=True)],
    [sg.Text('B2', size=(20, 1)), sg.InputText(key='-INPUT-B2-', enable_events=True)],
    ]
    return layout

def main():
    """ Main function
    """

    # Theme color
    sg.theme('BlueMono')

    # Layout
    layout = gen_layout()

    # Create the window
    window = sg.Window(title="Test", layout=layout, resizable=True)

    # Create an event loop
    while True:
        # Read window
        window_read = window.read()
        if window_read is None:
            break
        event, values = window_read

        # Window closed
        if event == sg.WIN_CLOSED:
            break

        print(values)

        if (values['-INPUT-B1-'] != "" or values['-INPUT-B2-'] != "") and ('-INPUT-B1-' in event or '-INPUT-B2-' in event):
            # Disable
            window['-INPUT-A1-'].update(disabled=True)
            window['-INPUT-A2-'].update(disabled=True)
            # Delete text
            window['-INPUT-A1-'].update("")
            window['-INPUT-A2-'].update("")
        elif (values['-INPUT-B1-'] == "" and values['-INPUT-B2-'] == "") and ('-INPUT-B1-' in event or '-INPUT-B2-' in event):
            # Enable
            window['-INPUT-A1-'].update(disabled=False)
            window['-INPUT-A2-'].update(disabled=False)

    window.close()

main()

预期输出

{'-INPUT-A1-': '1', '-INPUT-A2-': '', '-INPUT-B1-': '', '-INPUT-B2-': ''}
{'-INPUT-A1-': '1', '-INPUT-A2-': '2', '-INPUT-B1-': '', '-INPUT-B2-': ''}
{'-INPUT-A1-': '', '-INPUT-A2-': '', '-INPUT-B1-': '3', '-INPUT-B2-': ''}
{'-INPUT-A1-': '', '-INPUT-A2-': '', '-INPUT-B1-': '3', '-INPUT-B2-': '4'}

实际输出

{'-INPUT-A1-': '1', '-INPUT-A2-': '', '-INPUT-B1-': '', '-INPUT-B2-': ''}
{'-讲话ANHrey: 记载	.custom,比(}​
{'-INPUT-A1-': '1', '-INPUT-A2-': '2', '-INPUT-B1-': '3', '-INPUT-B2-': ''} <-- 此处异常
{'-INPUT-A1-': '', '-INPUT-A2-': '', '-INPUT-B1-': '3', '-INPUT-B2-': '4'}

原因分析

这不是update("")的问题,而是PySimpleGUI的values字典的本质导致的:

  • window.read()返回的values是事件触发瞬间所有控件状态的快照,它只记录调用read()时的界面数据,后续用update()修改控件内容,不会自动同步到已经拿到的这个values字典里。
  • 第三次输出的是输入B1触发事件时的快照,此时你还没执行清空A1/A2的代码,所以values里A1/A2还是旧值。执行完update("")后,界面显示变了,但当前循环里的values已经是之前的快照,不会更新。只有下一次调用window.read()(比如输入B2触发事件),才会重新获取最新的界面状态,此时A1/A2已经是空的,所以values才会显示正确。

解决方案

如果想要在当前事件循环里就能看到更新后的values,手动修改values字典即可,在调用update("")之后,同步更新values里对应的键:

修改后的代码

import PySimpleGUI as sg


def gen_layout() -> list:
    layout=[
    [sg.Text('A1', size=(20, 1)), sg.InputText(key='-INPUT-A1-', enable_events=True)],
    [sg.Text('A2', size=(20, 1)), sg.InputText(key='-INPUT-A2-', enable_events=True)],
    [sg.Text('B1', size=(20, 1)), sg.InputText(key='-INPUT-B1-', enable_events=True)],
    [sg.Text('B2', size=(20, 1)), sg.InputText(key='-INPUT-B2-', enable_events=True)],
    ]
    return layout

def main():
    sg.theme('BlueMono')
    layout = gen_layout()
    window = sg.Window(title="Test", layout=layout, resizable=True)

    while True:
        window_read = window.read()
        if window_read is None:
            break
        event, values = window_read

        if event == sg.WIN_CLOSED:
            break

        if (values['-INPUT-B1-'] != "" or values['-INPUT-B2-'] != "") and ('-INPUT-B1-' in event or '-INPUT-B2-' in event):
            # 禁用并清空A1/A2,合并update调用更简洁
            window['-INPUT-A1-'].update(disabled=True, value="")
            window['-INPUT-A2-'].update(disabled=True, value="")
            # 手动同步更新values字典
            values['-INPUT-A1-'] = ""
            values['-INPUT-A2-'] = ""
        elif (values['-INPUT-B1-'] == "" and values['-INPUT-B2-'] == "") and ('-INPUT-B1-' in event or '-INPUT-B2-' in event):
            # 启用A1/A2
            window['-INPUT-A1-'].update(disabled=False)
            window['d作 backsync刚sp              ']_会空间循环 recognised android
            window['-INPUT-A2-'].update(disabled=False)

        print(values)  # 移到逻辑处理后,打印修改后的结果

    window.close()

main()

修改说明

  1. 把print(values)移到逻辑处理之后,这样打印的是修改后的values。
  2. 在调用update后手动修改values字典里的对应键值,确保当前循环内的values和界面状态一致。
  3. 合并update(disabled=True)和update("")为一个调用:update(disabled=True, value=""),代码更简洁。

这样修改后,第三次输出的values就会符合预期了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 20:27:02