使用tkinter搭配pynput时触发Illegal Instruction:4错误求助
使用pynput结合Tkinter开发自动输入工具时触发Illegal Instruction:4错误
我尝试用pynput配合Tkinter开发自动键盘输入工具,把pynput的输入逻辑放到自定义线程里执行。单独跑pynput的输入逻辑完全正常,但和Tkinter结合后程序就崩溃,提示Illegal Instruction:4。
根据@Karl的建议,我制作了最小复现示例,代码如下:
import tkinter,threading,pynput,time keyb = pynput.keyboard.Controller() global thread_save def typer(*args): while True: # print("spam") keyb.type("hi") time.sleep(0.1) def beginning(*args): global thread_saved print("pressed") thread_saved = threading.Thread(target=typer) thread_saved.start() thread_saved.run() root = tkinter.Tk() but = tkinter.Button(text="Begin",master=root) but.bind("<1>",beginning) but.pack() root.mainloop()
结果对比
- 预期结果:点击按钮后,键盘持续输出“hi”
- 当前结果:程序崩溃并提示Illegal Instruction:4
环境信息
- 系统版本:MacOS 10.15.7(Intel芯片Mac)
- 依赖包版本:
pynput==1.7.6 pyobjc-core==10.0 pyobjc-framework-ApplicationServices==10.0 pyobjc-framework-Cocoa==10.0 pyobjc-framework-Quartz==10.0 six==1.16.0
解决方案
问题根源是同时调用了thread_saved.start()和thread_saved.run():
start()方法会创建一个新线程,并在新线程中自动调用run()执行目标函数- 手动调用
run()会让目标函数直接在Tkinter的主线程(UI线程)中执行,导致pynput的输入操作和Tkinter的事件循环冲突,触发底层错误
修复步骤:
- 删除
thread_saved.run()这一行,只保留start()启动线程 - 可选优化:给线程加上
daemon=True,关闭窗口时自动终止线程;添加线程存活判断,防止重复点击创建多个输入线程
修改后的代码:
import tkinter, threading, pynput, time keyb = pynput.keyboard.Controller() thread_saved = None def typer(): while True: keyb.type("hi") time.sleep(0.1) def beginning(*args): global thread_saved print("pressed") # 避免重复创建线程 if thread_saved is None or not thread_saved.is_alive(): # daemon=True:窗口关闭时线程自动退出 thread_saved = threading.Thread(target=typer, daemon=True) thread_saved.start() root = tkinter.Tk() but = tkinter.Button(text="Begin", master=root) but.bind("<1>", beginning) but.pack() root.mainloop()
内容的提问来源于stack exchange,提问作者DarthVaderFan
相关产品推荐
相关产品推荐

