Python实例化类时如何向函数传参?Tkinter图片类参数传递问题
解决方案
1 修复基础错误
- 导入语句拼写错误:
from tkinter importante *改为from tkinter import * Show_image类构造函数参数顺序错误,Frame子类的第一个参数必须为父容器master,调整构造函数定义:
class Show_image(Frame): # 调整参数顺序,master放首位,再传入两个索引参数 def __init__(self, master, index_1, index_2, *args, **kwargs): Frame.__init__(self, master, *args, **kwargs) # 原有业务逻辑保持不变
2 实现索引参数传入
修改Interface类的回调逻辑,支持透传索引参数:
- 修改按钮的command回调,传入需要展示的两个图片索引,示例使用索引0和1对应前两张图:
self.button1 = Button(self, text='pack 1', command= lambda:self.windows(Show_image, 0, 1))
- 修改
windows方法,接收可变参数并传入对应类的构造函数:
def windows(self, var_1, *args): if not self._open_1: self.top1 = Toplevel(self.master) self.top1.geometry('200x200') # 把接收的索引参数传入类构造函数 container = var_1(self.top1, *args) # 后续原有逻辑保持不变
3 图片路径说明
你当前使用的是相对路径,会从Python脚本的运行工作目录下查找对应图片文件,有效性判断规则:
- 若图片和脚本放在同一文件夹下,直接写文件名的写法正确
- 若图片不在同一目录,建议写绝对路径,Windows下格式为
r'C:\xxx\11.png',macOS/Linux下格式为'/home/xxx/11.png' - 可提前通过
os.path.exists(路径)方法校验路径有效性,避免文件找不到报错。
完整可运行修改后代码
from tkinter import * from PIL import Image, ImageTk import os # 可选,用于路径校验 class Array(Frame): def __init__(self, master, path, *args): Frame.__init__(self, master, *args) # 路径校验可选,可删除 if not os.path.exists(path): raise FileNotFoundError(f"图片不存在:{path}") self.image = Image.open(path) self.img_copy = self.image.copy() self.background_image = ImageTk.PhotoImage(self.image) self.background = Label(self, image=self.background_image) self.background.pack(fill='both', expand=True) self.background.bind('<Configure>', self._resize_image) def _resize_image(self, event): # 调整缩放尺寸,避免两张图溢出窗口 self.image = self.img_copy.resize((self.master.winfo_width()//2, self.master.winfo_height()//2)) self.background_image = ImageTk.PhotoImage(self.image) self.background.configure(image=self.background_image) class Interface(Frame): def __init__(self, master, *args): Frame.__init__(self, master, *args) self.path_lst = ['11.png','22.png','33.png','44.png'] # 按需修改路径 self._frame_1 = None self._open_1 = False # 传入需要展示的两个图片索引,示例为第1、2张(索引0和1) self.button1 = Button(self, text='pack 1', command= lambda:self.windows(Show_image, 0, 1)) self.button1.pack() def windows(self, var_1, *args): if not self._open_1: self.top1 = Toplevel(self.master) self.top1.geometry('400x400') # 调整窗口大小适配两张图 container = var_1(self.top1, *args) if self._frame_1 is not None: self._frame_1.destroy() self._frame_1 = container self._frame_1.pack(fill='both', expand=True) self._open_1 = True self.top1.protocol('WM_DELETE_WINDOW', lambda: self.closed(1)) def closed(self, number): if number == 1: self.top1.destroy() self._open_1 = False class Show_image(Frame): def __init__(self, master, index_1, index_2, *args, **kwargs): Frame.__init__(self, master, *args, **kwargs) self.img = Array(self, self.master.path_lst[index_1]) self.img.grid(column=0, row=0, padx=5, pady=5) self.img2 = Array(self, self.master.path_lst[index_2]) self.img2.grid(column=0, row=1, padx=5, pady=5) root = Tk() frm = Interface(root) frm.pack() root.mainloop()
内容的提问来源于stack exchange,提问作者Benjamin
相关产品推荐
相关产品推荐

