如何在Tkinter子菜单选中时调用外部Python文件中的函数?
实现Tkinter菜单调用外部函数并保持文件分离
没问题,这事儿很容易搞定,咱们分几步来,既能保持gui.py和main.py分离,又能让点击菜单触发摄像头拍摄功能,还能避免GUI假死的问题:
步骤1:在gui.py中导入main.py的函数
因为两个文件在同一目录下,直接在gui.py的顶部导入TakeSnapAndSave函数就行:
from tkinter import* from main import TakeSnapAndSave # 新增这行,导入外部函数
步骤2:修改菜单命令绑定
找到subMenu.add_command(label="Web Cam", command=needTodo)这一行,把command参数换成我们导入的函数:
subMenu.add_command(label="Web Cam", command=TakeSnapAndSave)
步骤3:修复main.py里的小错误
注意你的main.py里有个拼写错误:cv2.desrtoyAllWindows()应该改成cv2.destroyAllWindows(),不然运行会报错。另外函数末尾的break会让循环只执行一次就退出,如果你想拍满1000张可以去掉这个break,按需调整就行。
进阶:避免GUI假死(重要!)
直接绑定函数的话,点击Web Cam后,Tkinter的GUI会卡住,直到TakeSnapAndSave执行完毕——因为Tkinter是单线程的,主线程被摄像头循环占用了。解决办法是用threading模块把拍摄函数放到子线程里运行:
修改gui.py,新增线程相关代码:
from tkinter import* from main import TakeSnapAndSave import threading # 导入线程模块 def run_camera(): # 把摄像头函数放到子线程执行,daemon=True保证退出GUI时线程也会终止 threading.Thread(target=TakeSnapAndSave, daemon=True).start() def needTodo(): #Enter your code pass root = Tk() root.title('Something') # ******** MAIN MENU ******** # menu = Menu(root) root.config(menu=menu) root.minsize(320, 320) root.geometry("320x320") subMenu = Menu(menu) menu.add_cascade(label="File", menu=subMenu) subMenu.add_command(label="Insert Image", command=needTodo) subMenu.add_command(label="Web Cam", command=run_camera) # 这里改成调用线程函数 subMenu.add_separator() subMenu.add_command(label="Exit", command=needTodo) # 后面的Toolbar、Canvas、Status Bar代码保持不变...
这样点击Web Cam后,GUI依然能正常操作,摄像头拍摄在后台运行。
总结
- 通过导入语句实现跨文件函数调用,完美保持代码分离
- 用线程解决Tkinter单线程导致的GUI假死问题
- 修复main.py里的拼写错误避免运行报错
内容的提问来源于stack exchange,提问作者Azazel
相关产品推荐
相关产品推荐

