使用Tkinter开发进程联动程序时遇GUI卡顿问题求助
问题分析与解决方案
你的程序卡顿的核心原因是在tkinter主线程中执行了耗时的进程遍历操作。psutil.process_iter()会枚举系统所有进程,这个操作需要一定时间,而tkinter是单线程模型,主线程被阻塞时,UI更新(比如upd方法里的计数器刷新)就会停滞,导致界面卡顿。
修复方案:用子线程处理进程检查逻辑
把进程检测的任务放到独立线程中执行,让主线程专注处理UI交互和更新。子线程不能直接操作tkinter的UI元素,所以需要通过win.after()方法向主线程发送消息,由主线程处理弹窗或窗口关闭。
修改后的代码如下:
import tkinter as tk from tkinter import messagebox import psutil import os import threading import time class myapp(): def __init__(self): self.win = tk.Tk() self.win.title("test") self.win.geometry('200x100') self.win.config(bg='black') self.win.resizable(False,False) self.ctr = 0 self.tk_var = tk.StringVar() self.tk_var.set("0") self.running = True # 控制子线程运行的标志 lab=tk.Label(self.win, textvariable=self.tk_var, bg='black', fg='#FF0000') lab.place(x=90, y=45) btn = tk.Button(self.win,text='test',command='', bd=0,bg='#7E1600',width=10, activebackground='#6D0000') btn.pack(pady=20) self.upd() # 启动子线程处理进程检查 threading.Thread(target=self.test, daemon=True).start() self.win.mainloop() def upd(self): if self.running: self.ctr += 1 self.tk_var.set(str(self.ctr)) self.win.after(50,self.upd) def test(self): while self.running: # 检查进程是否存在 process_exists = "notepad.exe" in (i.name() for i in psutil.process_iter()) if not process_exists: # 通知主线程显示弹窗 self.win.after(0, self.show_error_and_exit) break time.sleep(0.5) # 每隔0.5秒检查一次 def show_error_and_exit(self): er = messagebox.showerror(title='error', message='notepad.exe has been stopped') if er == 'ok': self.running = False self.win.destroy() os.popen('notepad') myapp()
关键修改点:
- 添加
self.running标志,用于控制子线程和UI更新循环的启停 - 将
test方法放到子线程中执行,用time.sleep(0.5)替代after实现定时检查 - 子线程中通过
self.win.after(0, ...)触发主线程执行UI相关操作(弹窗、关闭窗口) - 设置子线程为
daemon=True,确保主线程退出时子线程也会自动结束
这样修改后,进程检查的耗时操作不会阻塞主线程,UI就能保持流畅更新,同时也能实现进程联动的需求。
内容的提问来源于stack exchange,提问作者Farhan Adabi
相关产品推荐
相关产品推荐

