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

点击FreeSimpleGUI的Close按钮弹出错误弹窗,寻求解决方法

解决FreeSimpleGUI窗口关闭按钮报错问题

问题描述

我用FreeSimpleGUI开发了一个待办事项列表界面,点击“Exit”按钮程序能正常关闭,但点击窗口自带的“Close”按钮时会弹出错误弹窗,请问该怎么解决?这是我第一次发帖,若格式有问题请见谅。

代码示例

import functions
import FreeSimpleGUI as sg
import time
import os

if not os.path.exists("todos.txt"):
    with open("todos.txt", "w") as file:
        pass

sg.theme("Black")

clock = sg.Text('', key='clock')
label = sg.Text("Type in a to-do")
input_box = sg.InputText(tooltip="Enter to-do", key="todo")
add_button = sg.Button("Add")
list_box = sg.Listbox(values=functions.get_todos(), key='todos',
                      enable_events=True, size=[45, 10])
edit_button = sg.Button("Edit")
complete_button = sg.Button("Complete")
exit_button = sg.Button("Exit")

window = sg.Window('My To-Do App',
                   layout=[[clock],
                           [label],
                           [input_box, add_button],
                           [list_box, edit_button, complete_button],
                           [exit_button]],
                   font=('Helvetica', 20))

while True:
    event, values = window.read(timeout=500)
    window["clock"].update(value=time.strftime("%b %d, %Y %H:%M:%S"))
    match event:
        case "Add":
            todos = functions.get_todos()
            new_todo = values['todo'] + "\n"
            todos.append(new_todo)
            functions.write_todos(todos)
            window['todos'].update(values=todos)

        case "Edit":
            try:
                todo_to_edit = values['todos'][0]
                new_todo = values['todo'] + "\n"

                todos = functions.get_todos()
                index = todos.index(todo_to_edit)
                todos[index] = new_todo
                functions.write_todos(todos)
                window['todos'].update(values=todos)
            except IndexError:
                sg.popup("Please select an item first", font=("Helvetica", 20))

        case "Complete":
            try:
                todo_to_complete = values['todos'][0]
                todos = functions.get_todos()
                todos.remove(todo_to_complete)
                functions.write_todos(todos)
                window['todos'].update(values=todos)
                window['todo'].update(value='')
            except IndexError:
                sg.popup("Please select an item first", font=("Helvetica", 20))

        case "Exit":
            break
        case 'todos':
            window['todo'].update(value=values['todos'][0])
        case sg.WIN_CLOSED:
            break

window.close()

问题原因

点击窗口Close按钮触发sg.WIN_CLOSED事件后,代码虽然执行了break退出循环,但在这之前已经执行了window["clock"].update(...)——此时窗口已经进入关闭流程,调用界面元素的update方法会触发报错。

修复方案

把窗口关闭和Exit按钮的判断移到界面更新操作之前,确保触发关闭事件时直接退出循环,跳过所有后续的界面更新逻辑:

修改后的主循环代码:

while True:
    event, values = window.read(timeout=500)
    
    # 优先处理关闭事件,直接退出循环
    if event == sg.WIN_CLOSED or event == "Exit":
        break
    
    # 仅窗口正常运行时执行界面更新和事件处理
    window["clock"].update(value=time.strftime("%b %d, %Y %H:%M:%S"))
    match event:
        case "Add":
            todos = functions.get_todos()
            new_todo = values['todo'] + "\n"
            todos.append(new_todo)
            functions.write_todos(todos)
            window['todos'].update(values=todos)

        case "Edit":
            try:
                todo_to_edit = values['todos'][0]
                new_todo = values['todo'] + "\n"

                todos = functions.get_todos()
                index = todos.index(todo_to_edit)
                todos[index] = new_todo
                functions.write_todos(todos)
                window['todos'].update(values=todos)
            except IndexError:
                sg.popup("请先选择一个项目", font=("Helvetica", 20))

        case "Complete":
            try:
                todo_to_complete = values['todos'][0]
                todos = functions.get_todos()
                todos.remove(todo_to_complete)
                functions.write_todos(todos)
                window['todos'].update(values=todos)
                window['todo'].update(value='')
            except IndexError:
                sg.popup("请先选择一个项目", font=("Helvetica", 20))

        case 'todos':
            window['todo'].update(value=values['todos'][0])

window.close()

核心修复点

  • 提前判断sg.WIN_CLOSED和Exit事件,触发后直接退出循环,避免执行后续的界面更新操作
  • 所有界面元素的update方法仅在窗口正常运行时调用,从根源上避免窗口关闭后操作界面的错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 04:26:05