[问题] Tkinter 用 after 模拟弹出视窗卡住

楼主: jakeasa123 (啊斑斑)   2020-02-10 10:32:34
近日写了一个小程式,
期望功能是可以连接到我自己的数据库,
定时确认特定资料表的几个字段最新的数值并显示出来。
程式运作的期望流程是:
1. 连线数据库并抓取当下最新的资料
2. 用 after 每隔 5 秒呼叫确认资料的函式
3. 若检查到资料有更新时,使用 lift 把模拟弹出视窗的物件拉到顶层
  原本想用弹出视窗,但发现不时弹出来有点麻烦,所以改 lift 图片和 label 来模拟
4. lift 呈现 3 ~ 5 秒后,lower 这些模拟用物件使之消失
5. 继续进行 (2) 步骤
目前测试起来,
连线数据库与抓资料没问题、
抓好资料后更新显示的 label 没问题、
lift 与 lower 独立运作没问题、
用 after 每隔 5 秒呼叫确认资料的函式没问题,
但如果结合让模拟的弹出视窗呈现数秒就会卡住(目前我这边也是用 after)。
def 更新资料:
// 更新资料的过程
if 新资料有变动:
模拟用物件.lift()
after(3000, 模拟物件lower的函式)
after(5000, 更新资料)
(抱歉程式不在手边没办法直接贴)
上述这样子运作时,
程式进了 if 内的 after 会整个卡住且会有“没有回应”的讯息,
但过了 if 内的 3 秒,
资料显示还是可以正常运作(但模拟弹出视窗就完全看不见了)。
想过不要用 after 来呼叫 lower,
而是用一个 flag 来确认有没有需要 lift 或 lower,
但这样子的 lift 或 lower 会跟着 after(5000, 更新资料) 这行动作,
一次若有数个字段更新时,
就没办法逐一显示,
只会显示最后一个更新的字段。
现阶段小弟想到的解决办法是延续上段的方法,
但要用模拟弹出视窗的资料转用 list 保存,
每次都检查 list 内有没有资料,
有资料就 lift 并将 list[0] 的资料呈现后删除。
想请教这种情形下有没有更合适的解法?
在此先谢谢各位前辈花费时间阅读了,感谢!
作者: poototo (poototo)   2020-02-10 13:01:00
纯经验分享,觉得tinker似乎效能不佳?也有用tk的一些控件来想办法显示资料处理的进度爬虫,db,档案等IO存取...少量以为OK,大量一下子就卡
作者: stucode   2020-02-10 19:16:00
检查看看“模拟物件lower的函式”那里有没有执行什么长时间操作。一般会卡到没有回应表示你程式的某部分占用了GUI 主循环的执行绪。把它提出来放到另一个执行绪处理。如果找不到就先做 profiling 确认 call graph。也可以看看是不是有把 after(1,foo) 写成 after(1,foo())
楼主: jakeasa123 (啊斑斑)   2020-02-11 10:40:00
谢谢两位前辈建议,小弟再确认一下

Links booklink

Contact Us: admin [ a t ] ucptt.com