Tkinter如何实现点击按钮终止while循环及对应Selenium任务
实现方案
核心思路是给每个启动的Selenium任务单独绑定运行状态标志位、驱动实例,同时将阻塞的长休眠拆分为带状态检查的短休眠,保证点击按钮后可以立即中断执行。
关键修改点
- 新增全局存储结构保存每个任务的运行状态、Selenium驱动实例,避免变量覆盖
- 为close按钮绑定对应任务序号,点击时精准修改指定任务的运行标志
- 将长sleep拆分为循环短sleep,每次休眠前检查运行标志,实现即时中断
- 修正原代码的笔误(缺失threading导入、Entry4笔误、按钮与方法重名等问题)
修改后完整代码
from tkinter import * from selenium import webdriver from time import sleep import threading # 原代码缺失导入 class screen(): def __init__(self): self.no = 1 # 存储所有运行中的任务,key为任务序号,value存储驱动和运行状态 self.running_tasks = {} def close(self, task_no): # 拿到对应任务的信息 task = self.running_tasks.get(task_no) if not task: return # 修改运行标志为False task['is_running'] = False # 关闭Selenium驱动,彻底退出进程 try: task['driver'].quit() except: pass # 移除记录 del self.running_tasks[task_no] # 销毁对应close按钮 task['close_btn'].destroy() def go(self,a,b,c,d): # 不要和close方法重名,改名为close_btn # 用lambda传递当前任务序号给close方法 close_btn = Button(self.window, text=f"{d}close", width=10, height=2, command=lambda : self.close(d)) close_btn.grid(row=4+d,column=1,columnspan=3,padx=5, pady=5) driver = webdriver.Chrome(executable_path="webdriver") # 初始化当前任务的运行状态 self.running_tasks[d] = { 'is_running': True, 'driver': driver, 'close_btn': close_btn } # 循环条件改为判断当前任务的运行标志 while self.running_tasks[d]['is_running']: driver.get(a) # 长sleep拆分为短循环,每次检查运行状态,实现即时中断 for _ in range(11): if not self.running_tasks[d]['is_running']: break sleep(1) if not self.running_tasks[d]['is_running']: break print("1 done") driver.get(b) for _ in range(5): if not self.running_tasks[d]['is_running']: break sleep(1) if not self.running_tasks[d]['is_running']: break print("2 done") driver.get(c) for _ in range(5): if not self.running_tasks[d]['is_running']: break sleep(1) if not self.running_tasks[d]['is_running']: break print("3 done") print(f"we will go to your {d}th 3 website again") # 循环退出后确保驱动关闭 try: driver.quit() except: pass def start(self): a = self.Entry1.get() b = self.Entry2.get() c = self.Entry3.get() self.no = self.no + 1 thread = threading.Thread(target=self.go, args=[a,b,c,self.no], daemon=True).start() def tkin(self): self.window = Tk() self.window.title("selenium task") self.label1 = Label(self.window, text="enter your 1 website") self.Entry1 = Entry(self.window) self.label2 = Label(self.window, text="enter your 2 website") self.Entry2 = Entry(self.window) self.label3 = Label(self.window, text="enter your 3 website") self.Entry3 = Entry(self.window) self.button = Button(self.window, text="start", width = 10 , height = 2 , command = self.start) self.label1.grid(row=1,column=1, columnspan = 3, padx=5, pady=5) self.Entry1.grid(row=1,column=2, columnspan = 3, padx=5, pady=5) self.label2.grid(row=2,column=1, columnspan = 3, padx=5, pady=5) self.Entry2.grid(row=2,column=2, columnspan = 3, padx=5, pady=5) self.label3.grid(row=3,column=1, columnspan = 3, padx=5, pady=5) # 原代码Entry4是笔误,改为Entry3 self.Entry3.grid(row=3,column=2, columnspan = 3, padx=5, pady=5) self.button.grid(row=4,column=1, columnspan = 3, padx=5, pady=5) self.window.mainloop() # 运行示例 if __name__ == "__main__": s = screen() s.tkin()
效果说明
点击对应序号的close按钮后,会立即将对应任务的运行标志设为False,下一次状态检查时就会直接退出循环,同时关闭对应Selenium驱动,不需要等待当前sleep执行完成。
内容的提问来源于stack exchange,提问作者Hesham Ibrahim
相关产品推荐
相关产品推荐

