Tkinter多进程运行报NameError: name 'logarea' is not defined怎么解决
问题解决方案
根因说明
- Windows系统下
multiprocessing默认使用spawn模式启动子进程,子进程会重新导入当前脚本,不会执行if __name__ == '__main__'下的初始化代码,因此子进程中不存在logarea全局变量,触发NameError。 - Tkinter为单线程UI框架,禁止在非主线程/非主进程中直接操作UI组件,即使解决变量问题也会导致UI崩溃。
修正思路
使用multiprocessing.Queue实现进程间通信,子进程仅负责执行自动化任务、生产日志内容并写入队列,主进程启动定时任务轮询队列获取日志,更新到UI文本框中。
完整可运行代码
from tkinter import * from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options import time import multiprocessing from multiprocessing import Queue import os from tkinter import ttk import logging import datetime curr_dir = os.getcwd() # 全局日志队列,用于进程间传递日志内容 log_queue = Queue() def browserRun(): global curr_dir # 自动创建Logs文件夹,避免写入失败 os.makedirs(os.path.join(curr_dir, 'Logs'), exist_ok=True) timenow = datetime.datetime.now().strftime("%Y%m%d%H%M%S") logname = rf'{curr_dir}\Logs\Log-{timenow}.txt' logging.basicConfig(filename=logname, filemode='a', format='%(asctime)s: %(message)s', datefmt='%d-%m-%Y %I:%M:%S %p', level=logging.INFO, force=True) while True: global driver options = Options() options.binary_location = r'D:\Downloads\Chromedriver\browser\chrome.exe' driver = webdriver.Chrome(executable_path=r'D:\Downloads\Chromedriver\chromedriver.exe', options=options) driver.get('http://google.com') log_content = f"{datetime.datetime.now().strftime('%d-%m-%Y %I:%M:%S %p')}: Logging to gmail\n" logging.info(log_content) # 日志写入队列,不直接操作UI log_queue.put(log_content) time.sleep(5) driver.find_element(By.XPATH, '//input[@name="q"]').send_keys("Hello World") log_content = f"{datetime.datetime.now().strftime('%d-%m-%Y %I:%M:%S %p')}: 输入Hello World完成\n" logging.info(log_content) log_queue.put(log_content) time.sleep(5) driver.close() driver.quit() def start(): global executor executor = [multiprocessing.Process(target=browserRun) for _ in range(1)] for p in executor: p.daemon = True p.start() def update_log(): # 主进程定时读取队列,更新UI global logarea, log_queue while not log_queue.empty(): content = log_queue.get() logarea.config(state='normal') logarea.insert(END, content) logarea.see("end") logarea.config(state='disabled') # 每秒轮询一次队列 root.after(1000, update_log) def stop(): global executor for p in executor: p.terminate() os.system("taskkill /F /IM CHROME.exe /T") if __name__ == '__main__': global logarea root = Tk() notebook = ttk.Notebook(root, style='lefttab.TNotebook') tab1 = ttk.Frame(notebook) tab2 = ttk.Frame(notebook) notebook.add(tab1, text="Home") notebook.add(tab2, text="Settings") notebook.pack(fill=BOTH, expand=True) button = Button(tab1, text="start", command=start) button.place(x=20, y=20) button1 = Button(tab1, text="stop", command=stop) button1.place(x=70, y=20) logarea = Text(tab1, height=25, width=80, wrap='word', state='disabled') logarea.place(x=120, y=40) root.geometry("800x500") # 启动日志更新定时任务 update_log() root.mainloop()
内容的提问来源于stack exchange,提问作者sunny9495
相关产品推荐
相关产品推荐

