You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter Canvas带滚动条显示图片触发TypeError错误,请求技术排查帮助

Fixing Your Tkinter Canvas Scrollbar & Image Display Issues

Let's break down the problems in your code and fix them one by one:

1. Direct Cause of the Latest TypeError

The line canvas.config(self.image_on_canvas) is the source of your TypeError: object of type 'int' has no len() error.

  • self.image_on_canvas is an integer ID returned by canvas.create_image(), which identifies the image item on the canvas.
  • The canvas.config() method is meant to set properties of the canvas itself (like size or scroll commands), not modify individual items on it. Passing an integer ID here makes no sense to Tkinter.

Fix: Delete this line entirely—it's unnecessary for your current code.

2. Preventing Image Disappearance (Garbage Collection Issue)

You're creating img2 = ImageTk.PhotoImage(img) as a local variable inside your loop. Tkinter PhotoImages are prone to being garbage collected if there's no persistent reference to them, which would make your image vanish after the function runs.

Fix: Store the PhotoImage as an instance variable to keep it alive:

img2 = ImageTk.PhotoImage(img)
self.canvas_img = img2  # Keep reference to avoid garbage collection
self.image_on_canvas = canvas.create_image(0, 0, anchor="nw", image=img2)

3. Avoiding Duplicate UI Elements

Your for database_visuales2 in db_rows: loop will create multiple frames, buttons, and canvases if your query returns more than one row (which it shouldn't, since you're querying by ID_IMAGEN_VISUAL). To prevent overlapping UI elements, add a break after processing the first row:

for database_visuales2 in db_rows:
    # ... all your existing code for this iteration ...
    break  # Exit loop after first row (since ID should be unique)

Corrected Code Snippet

Here's the revised section of your function with all fixes applied:

def visualizar_imagen_consulta(self):
    try:
        self.tree3.item(self.tree3.selection())['values'][0]
    except IndexError as e:
        messagebox.showinfo("A T E N C I O N ! ! !", "Selecciones una consulta, por favor!")
        return
    self.windows_fichas_consulta2 = Toplevel()
    self.windows_fichas_consulta2.transient(self.windows_consulta1)
    self.windows_fichas_consulta2.resizable(width=False, height=False)
    self.windows_fichas_consulta2.geometry("655x600+700+0")
    query = 'SELECT * FROM visuales WHERE ID_IMAGEN_VISUAL = ?'
    parameters = (self.miid_nombre_imagen.get(), )
    db_rows = self.run_query(query, parameters)
    
    for database_visuales2 in db_rows:
        self.midescripcion_imagen.set(database_visuales2[4])
        self.tarjeta_ficha_consulta1="/oftica/visuales/" + self.miid_nombre_imagen.get()
        
        # Frame for menu
        self.frame200 = LabelFrame(self.windows_fichas_consulta2, text = '', foreground = 'darkgreen', font = ('arial', 16, 'bold'), background='lightcyan2')
        self.frame200.place(x=70, y=510)
        Button(self.frame200, text = ' Escuchar', command = self.voz_imagen_consulta, background="cyan4", image=self.photo_tarjeta_speaker, compound="left", height = 30, width = 150, foreground = 'black', font = ('arial', 12, 'bold')).grid(row = 1, column = 0, columnspan = 1, sticky = W + E, pady=5, padx=5)
        Button(self.frame200, text = ' Zoom', command = self.zoom_imagen_consulta2, background="cyan4", image=self.photo_zoom, compound="left", height = 30, width = 150, foreground = 'black', font = ('arial', 12, 'bold')).grid(row = 1, column = 1, columnspan = 1, sticky = W + E, pady=5, padx=5)
        Button(self.frame200, text = ' Volver', command = lambda : self.windows_fichas_consulta2.destroy(), background="seaGreen3", image=self.photo_volver_consulta, compound="left", height = 30, width = 150, foreground = 'black', font = ('arial', 12, 'bold')).grid(row = 1, column = 2, columnspan = 1, sticky = W + E, pady=5, padx=5)
        Label(self.frame200, text = '' + self.midescripcion_imagen.get(), font = ('arial', 12, 'bold'), background='lightcyan2').grid(row = 0, column = 0, columnspan = 5, sticky = W + E, pady=5, padx=5)
        
        img_frame = tk.Frame(self.windows_fichas_consulta2, height=400, width=600, bg='#faf0e6')
        img_frame.pack()
        canvas = tk.Canvas (img_frame, height=400, width=600, bg='#faf0e6', relief=tk.SUNKEN)
        sbarV = tk.Scrollbar(img_frame, orient=tk.VERTICAL, command=canvas.yview)
        sbarH = tk.Scrollbar(img_frame, orient=tk.HORIZONTAL, command=canvas.xview)
        sbarV.pack(side=tk.RIGHT, fill=tk.Y)
        sbarH.pack(side=tk.BOTTOM, fill=tk.X)
        canvas.config(yscrollcommand=sbarV.set)
        canvas.config(xscrollcommand=sbarH.set)
        canvas.pack(side=tk.LEFT, expand=True, fill=tk.BOTH)
        
        img = Image.open(self.tarjeta_ficha_consulta1)
        width, height = img.size
        canvas.config(scrollregion=(0, 0, width, height))
        img2 = ImageTk.PhotoImage(img)
        self.canvas_img = img2  # Persist reference to avoid garbage collection
        self.image_on_canvas = canvas.create_image(0, 0, anchor="nw", image=img2)
        
        break  # Stop after first row (ID should be unique)

Notes on the Previous item configure Error

That error occurred because you likely tried calling canvas.itemconfigure() without passing the required item ID (the first argument). If you ever need to modify the image later (like for zooming), you'd use:

canvas.itemconfigure(self.image_on_canvas, image=new_photo_image)

Just make sure you pass the item ID first, then the properties to change.

内容的提问来源于stack exchange,提问作者Juan carlos Pantoja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 07:27:48