import PySimpleGUI as sg
import math
import time
import threading  # 改用标准库的 threading.Event
def calculate_sqrt_sum(window, stop_event):
    """后台计算函数"""
    total = 10_000_000
    sum_result = 0.0
    start_time = time.time()
    try:
        for i in range(1, total + 1):
            if stop_event.is_set():  # 检查是否被取消
                return None  # 返回 None 表示计算被取消
            sum_result += math.sqrt(i)
            # 每 100 万次更新一次进度
            if i % 1_000_000 == 0 or i == total:
                progress = i / total * 100
                elapsed = time.time() - start_time
                window.write_event_value('-UPDATE-', (progress, sum_result, elapsed))
        return (sum_result, time.time() - start_time)  # 返回结果和总用时
    except Exception as e:
        window.write_event_value('-ERROR-', str(e))
        return None
def main():
    stop_event = threading.Event()  # 使用 threading.Event 替代 sg.ThreadSafeEvent
    layout = [
        [sg.Text('计算 1000 万以内平方根之和')],
        [sg.ProgressBar(100, key='-PROGRESS-', size=(30, 20))],
        [sg.Multiline('', size=(40, 5), key='-OUTPUT-', autoscroll=True)],
        [sg.Text('结果:'), sg.Input('', key='-RESULT-', disabled=True)],
        [sg.Button('开始'), sg.Button('停止'), sg.Button('退出')]
    ]
    window = sg.Window('多线程计算示例', layout, finalize=True)
    while True:
        event, values = window.read()
        if event in (sg.WIN_CLOSED, '退出'):
            stop_event.set()  # 通知线程停止
            break
        elif event == '开始':
            window['-PROGRESS-'].update(0)
            window['-RESULT-'].update('')
            window['-OUTPUT-'].update('计算中...\n')
            stop_event.clear()
            window['开始'].update(disabled=True)
            window['停止'].update(disabled=False)
            # 启动后台任务
            window.perform_long_operation(
                lambda: calculate_sqrt_sum(window, stop_event),
                '-COMPLETED-'
            )
        elif event == '停止':
            stop_event.set()  # 通知线程停止
            window['-OUTPUT-'].print('\n尝试停止计算...')
            window['停止'].update(disabled=True)
        elif event == '-UPDATE-':
            progress, result, elapsed = values[event]
            window['-PROGRESS-'].update(int(progress))
            window['-OUTPUT-'].print(f'进度: {progress:.1f}%, 已用时: {elapsed:.2f}秒')
        elif event == '-COMPLETED-':
            result = values[event]  # 获取后台任务的返回值
            if result is None:
                window['-OUTPUT-'].print('\n计算被取消或出错')
            else:
                sum_result, elapsed = result
                window['-RESULT-'].update(f'{sum_result:.2f}')
                window['-OUTPUT-'].print(f'\n计算完成! 结果: {sum_result:.2f}, 总用时: {elapsed:.2f}秒')
            window['开始'].update(disabled=False)
        elif event == '-ERROR-':
            sg.popup_error(f'错误: {values[event]}')
            window['开始'].update(disabled=False)
    window.close()
if __name__ == '__main__':
    main()