import PySimpleGUI as sg
import math
import time
from threading import Event
def calculate_sqrt_sum(window, stop_event):
"""
后台计算函数:计算1亿以内自然数的平方根之和
"""
total = 100_000_000
batch_size = 1_000_000
sum_result = 0.0
start_time = time.time()
try:
for i in range(1, total + 1):
sum_result += math.sqrt(i)
# 进度更新
if i % batch_size == 0 or i == total:
progress = i / total * 100
elapsed = time.time() - start_time
# 发送进度更新事件(使用元组传递多个值)
window.write_event_value('-PROGRESS-', (
f'已处理 {i:,} 个数...',
progress,
sum_result,
elapsed
))
# 检查停止信号
if stop_event.is_set():
window.write_event_value('-CANCELED-', None)
return
# 计算完成
elapsed = time.time() - start_time
window.write_event_value('-DONE-', (sum_result, elapsed))
except Exception as e:
window.write_event_value('-ERROR-', str(e))
def main():
stop_event = Event()
layout = [
[sg.Text('1亿以内自然数平方根之和计算器')],
[sg.Text('计算进度:'), sg.ProgressBar(100, orientation='h', size=(30, 20), key='-PROGRESS-BAR-')],
[sg.Multiline('', size=(50, 8), key='-OUTPUT-', autoscroll=True)],
[sg.Text('结果:'), sg.Input('', key='-RESULT-', disabled=True, size=(30, 1))],
[sg.Text('用时:'), sg.Input('', key='-TIME-', disabled=True, size=(15, 1)), sg.Text('秒')],
[sg.Button('开始计算'), sg.Button('停止'), sg.Button('退出')]
]
window = sg.Window('后台计算示例', layout, finalize=True)
window['-PROGRESS-BAR-'].update(0)
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, '退出'):
stop_event.set()
break
elif event == '开始计算':
window['-PROGRESS-BAR-'].update(0)
window['-RESULT-'].update('')
window['-TIME-'].update('')
window['-OUTPUT-'].update('')
stop_event.clear()
window['开始计算'].update(disabled=True)
window['停止'].update(disabled=False)
# 启动后台线程
window.start_thread(
lambda: calculate_sqrt_sum(window, stop_event),
'-THREAD-'
)
elif event == '停止':
stop_event.set()
window['停止'].update(disabled=True)
# 处理来自线程的事件
elif event == '-PROGRESS-':
message, progress, result, elapsed = values[event]
window['-OUTPUT-'].print(message)
window['-PROGRESS-BAR-'].update(progress)
elif event == '-DONE-':
result, elapsed = values[event]
window['-RESULT-'].update(f'{result:.4f}')
window['-TIME-'].update(f'{elapsed:.2f}')
window['-OUTPUT-'].print('计算完成!')
window['开始计算'].update(disabled=False)
window['停止'].update(disabled=True)
elif event == '-CANCELED-':
window['-OUTPUT-'].print('计算已取消')
window['开始计算'].update(disabled=False)
window['停止'].update(disabled=True)
elif event == '-ERROR-':
sg.popup_error(f'计算出错: {values[event]}')
window['开始计算'].update(disabled=False)
window['停止'].update(disabled=True)
window.close()
if __name__ == '__main__':
main()