Python tkinter开发图像处理器 未调用方法自动执行问题
问题根源
程序启动时自动弹出文件选择框的核心原因是菜单命令的绑定写法错误:你在绑定"Abrir Imagen"菜单的回调时写了command=openImage(),带括号的写法会在代码执行到这行(也就是窗口初始化构建菜单的时候)立刻执行openImage函数,而不是把函数存起来等用户点击菜单时再调用。
另外你的代码里还有三个隐藏bug会导致后续选文件时报错:
filedialog.askopenfile()返回的是打开的文件IO对象,不是文件路径字符串,无法直接传给cv2.imread()- 文件类型过滤规则里的"所有文件"配置写的是
'*.',通配符缺失,无法正确匹配所有格式文件 - 没有处理用户点击取消选择文件的分支,用户点取消会直接触发类型错误
修复步骤
修正菜单命令绑定:去掉
openImage后面的括号,只传递函数引用,不要直接调用# 错误写法 filemenu.add_command(label="Abrir Imagen", command=openImage()) # 正确写法 filemenu.add_command(label="Abrir Imagen", command=openImage)如果后续需要给回调函数传参,用lambda表达式包裹即可,写法为
command=lambda: 你的函数(参数),不要直接加括号调用。修正openImage函数逻辑:
- 把
askopenfile换成askopenfilename获取文件路径字符串 - 补全文件类型匹配规则
- 增加用户取消选择的判断分支
- 删除opencv原生弹窗相关的多余代码(你用tkinter做界面不需要这两行)
def openImage(): fileLocation = filedialog.askopenfilename( initialdir='/', title='Selecciona Un Archivo', filetypes=( ('png files', '*.png'), ('jpg files', '*.jpg'), ('all files', '*.*') ) ) # 用户点击取消按钮时直接退出函数,避免报错 if not fileLocation: return global image image = cv2.imread(fileLocation) # 后续在这里加图像转tkinter可展示格式、渲染到框架的逻辑即可- 把
修正后的完整代码
import tkinter as tk from tkinter import filedialog from tkinter.ttk import Label import cv2 from PIL import Image, ImageTk import webbrowser def openImage(): fileLocation = filedialog.askopenfilename( initialdir='/', title='Selecciona Un Archivo', filetypes=( ('png files', '*.png'), ('jpg files', '*.jpg'), ('all files', '*.*') ) ) if not fileLocation: return global image image = cv2.imread(fileLocation) class Main(tk.Tk): def __init__(self): super().__init__() self.title('Programa de Manipulación de Imagenes de JMMS') self.geometry('600x600') # 注意确认你的triforce.ico路径正确,不存在的话可以先注释这行避免启动报错 # self.iconbitmap('tools/triforce.ico') menu = tk.Menu(self) filemenu = tk.Menu(menu, tearoff=0) filemenu.add_command(label="Abrir Imagen", command=openImage) filemenu.add_command(label="Guardar Imagen", command=None) filemenu.add_separator() filemenu.add_command(label="Salir", command=self.quit) menu.add_cascade(label="Archivo", menu=filemenu) toolsmenu = tk.Menu(menu, tearoff=0) toolsmenu.add_command(label="Zoom", command=None) menu.add_cascade(label="Herramientas", menu=toolsmenu) helpmenu = tk.Menu(menu, tearoff=0) helpmenu.add_command(label="Contacto", command=None) menu.add_cascade(label="Ayuda", menu=helpmenu) self.config(menu=menu) toolsFrame = tk.Frame(self, width=50, height=600, background='white') toolsFrame.grid(row=1, column=1) frame = tk.Frame(self, width=500, height=550, background='gray') frame.grid(row=1, column=2) frame3 = tk.Frame(self, width=50, height=600, background='white') frame3.grid(row=1, column=3) if __name__ == '__main__': main = Main() main.mainloop()
内容的提问来源于stack exchange,提问作者Mario Martínez
相关产品推荐
相关产品推荐

