未响应是为什么?
当我们的代码在后台运行的时候,CPU
会被抢占,此时我们的窗口将会停止刷新从而呈现未响应状态,操作系统认为我们程序已经停止。但是如果我们程序就需要耗费一些时间,怎么办呢?官方文档建议我们占用一个主线程来守护程序,具体就是让我们的 GUI
程序成为一个单独的线程,这样 GUI
就能持续占用 CPU
,这个问题也就迎刃而解。
如何做呢?
接上篇文章,我们计划将测速的步骤写成独立的方法,同时在主方法 start
中调用他们,然后在 GUI
的事件循环中起一个线程(将这个线程设置为守护线程)来执行主方法 start
,这样我们的未响应和实时刷新功能都可以解决。
代码
# -*- coding: utf-8 -*-
import PySimpleGUI as sg
from speedtest_cli import Speedtest
import threading
# 实例化测速对象
spt = Speedtest()
# 设置主题
sg.theme('BlueMono')
# 布局元素
one_line = [sg.Text('最佳服务器:'),sg.Text(size=(50,1),key='-BSTS-')]
two_line = [sg.Text('下载速度:'),sg.Text(size=(50,1),key='-DLS-')]
three_line = [sg.Text('上传速度:'),sg.Text(size=(50,1),key='-UPS-')]
four_line = [sg.Button('开始测试'),sg.Button('退出')]
five_line = [sg.Text(size=(50,1),key='-INFO-')]
# 布局
layout = [
one_line,
two_line,
three_line,
four_line,
five_line
]
def get_best_server(window):
window['-INFO-'].update('开始获取服务器...',text_color='red')
res = spt.best.get('sponsor')
print(res)
window['-BSTS-'].update(res,text_color='yellow')
def get_download_speed(window):
window['-INFO-'].update('开始获测试下载速率...',text_color='red')
dSp1=spt.download()
dSp=f'{dSp1/1024/1024:.2f} Mb/s'
window['-DLS-'].update(dSp,text_color='yellow')
def get_upload_speed(window):
window['-INFO-'].update('开始获测试上传速率...',text_color='red')
uSp1=spt.upload()
uSp=f'{uSp1/1024/1024:.2f} Mb/s'
window['-UPS-'].update(uSp,text_color='yellow')
def end(window):
window['-INFO-'].update('测试完成...',text_color='red')
def start(window):
get_best_server(window)
get_download_speed(window)
get_upload_speed(window)
end()
# 创建窗口
window = sg.Window('网速测试小工具', layout)
# 事件循环 event loop
while True:
event, values = window.read(timeout=100)
if event in (sg.WIN_CLOSED, '退出'):
# 用户关闭窗口或者点击退出后退出
break
if event == '开始测试':
# 解决由于代码执行耗时而导致窗口未响应的问题,使用threading(守护模式)解决
t1 = threading.Thread(target=start,daemon=True,args=[window])
t1.start()
print(f'Event: {event}')
print(str(values))
window.close()
效果
至此,问题完美解决~
Tip
- 主题要在布局前就设置
- 使用守护线程解决未响应的问题
- 业务逻辑在主方法中就完成编排
以上就是今天的全部内容了,感谢您的阅读,我们下节再会。
评论区