【问题标题】:Python Tkinter: AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'Python Tkinter:AttributeError:'PhotoImage'对象没有属性'_PhotoImage__photo'
【发布时间】:2020-10-25 11:04:24
【问题描述】:

编辑:当我使用 image = ImageTk.PhotoImage(resize_image) 而不是 file=resize_image 时,我的画布上没有显示任何内容。 See screenshot.

我正在创建一个图像查看器,它被分成四个框架,每个框架分别显示一个图像。目前,我注释掉了四帧中的三帧,以首先专注于修复异常。 我正在尝试在画布内显示图像,后者嵌入在屏幕左上角的frame_1 中。每当我运行我的代码时,我都会得到堆栈跟踪:

Traceback (most recent call last):
  File "c:/Users/EM/Desktop/Scripts/gui/slideshow_model/slide_show_class.py", line 67, in <module>
    slideshow_model.show_image(img1)
  File "c:/Users/EM/Desktop/Scripts/gui/slideshow_model/slide_show_class.py", line 55, in show_image
    image = ImageTk.PhotoImage(file=resize_image)
  File "C:\Users\EM\AppData\Local\Programs\Python\Python37\lib\site-packages\PIL\ImageTk.py", line 89, in __init__
    image = _get_image_from_kw(kw)
  File "C:\Users\EM\AppData\Local\Programs\Python\Python37\lib\site-packages\PIL\ImageTk.py", line 58, in _get_image_from_kw
    return Image.open(source)
  File "C:\Users\EM\AppData\Local\Programs\Python\Python37\lib\site-packages\PIL\Image.py", line 2852, in open
    prefix = fp.read(16)
AttributeError: 'Image' object has no attribute 'read'
Exception ignored in: <function PhotoImage.__del__ at 0x0000017EAD432D08>
Traceback (most recent call last):
  File "C:\Users\EM\AppData\Local\Programs\Python\Python37\lib\site-packages\PIL\ImageTk.py", line 118, in __del__
    name = self.__photo.name
AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'

这是我的课:

import tkinter as tk
from PIL import ImageTk, Image

root = tk.Tk()


class SlideshowModel():

    def __init__(self, master):
        self.master = root
        master.title('Basic Image Viewer')
        root.iconbitmap('../img/favicon.ico')
        root.state('zoomed')
        s_w = int(root.winfo_screenwidth())
        s_h = int(root.winfo_screenheight())
        self.grid_w = s_w // 2
        self.grid_h = s_h // 2
        self.frame_1 = tk.Frame(master, height=self.grid_h,
                                width=self.grid_w, bd=0)
        self.frame_1.grid(column=0, row=0)
        self.can = tk.Canvas(
            self.frame_1, width=(self.grid_w - 50), height=(self.grid_h - 50), bg="red")
        self.can.grid(row=0, column=0)
        self.frame_2 = tk.Frame(master, height=self.grid_h,
                                width=self.grid_w, bd=0, bg="black")
        self.frame_2.grid(column=1, row=0)
        self.frame_3 = tk.Frame(master, height=self.grid_h,
                                width=self.grid_w, bd=0, bg="black")
        self.frame_3.grid(column=0, row=1)
        self.frame_4 = tk.Frame(master, height=self.grid_h,
                                width=self.grid_w, bd=0, bg="black")
        self.frame_4.grid(column=1, row=1)


    # should return the image object
    def resize_image(self, img_path):
        image = Image.open(img_path)
        w_coeff = image.width / self.grid_w
        h_coeff = image.height / self.grid_h
        w_coeff = 1 / w_coeff if w_coeff > 1 else w_coeff
        h_coeff = 1 / h_coeff if h_coeff > 1 else h_coeff
        # pick the smallest coeff to get the image as small
        # as should be
        coeff = min(w_coeff, h_coeff)
        image = image.resize(
            (int(image.width * coeff), int(image.height * coeff)), Image.ANTIALIAS)
        return image

    # this function should show returned image
    # takes: image object, master frame
    def show_image(self, resize_image):
        image = ImageTk.PhotoImage(resize_image)
        # label = tk.Label(frame_x, image=image, bd=0)
        self.can.create_image(0, 0, image=image, anchor='nw')


slideshow_model = SlideshowModel(root)

img1 = slideshow_model.resize_image('../img/sample.jpg')

slideshow_model.show_image(img1)

root.mainloop()


我错过了什么? 更新:现在窗口毫无例外地打开,但图像仍然没有显示,我将canvas 涂成红色并将其宽度和高度减小了 50 像素,以便能够将其与框架,后者是彩色的(灰色/白色)。

【问题讨论】:

  • resize_image 不是文件,而是图像对象。所以ImageTk.PhotoImage(file=resize_image) 应该是ImageTk.PhotoImage(resize_image)
  • @Wups 我编辑了我的帖子。其实我直接用file=...而不是image对象,因为我在另一个线程上找到的,现在我把它取下来了,没有出现异常,但我的图像也没有显示。
  • image = ImageTk.PhotoImage(file=resize_image) 更改为image = ImageTk.PhotoImage(resize_image) 并且您忘记在self.can 上致电pack()grid()
  • show_image() 中将image 更改为self.image
  • 更新您在发布的代码中所做的更改。

标签: python tkinter


【解决方案1】:

问题是我的image = Image.open(...) 正在被垃圾收集,所以我必须添加self. 以免它被破坏。参见下面的代码 sn-p:

    def resize_image(self, img_path):
        self.image = Image.open(img_path)
        w_coeff = self.image.width / self.grid_w
        h_coeff = self.image.height / self.grid_h
        w_coeff = 1 / w_coeff if w_coeff > 1 else w_coeff
        h_coeff = 1 / h_coeff if h_coeff > 1 else h_coeff
        # pick the smallest coeff to get the image as small
        # as should be
        coeff = min(w_coeff, h_coeff)
        self.image = self.image.resize(
            (int(self.image.width * coeff), int(self.image.height * coeff)), Image.ANTIALIAS)
        return self.image

    def show_image(self, resize_image):
        self.image_tk = ImageTk.PhotoImage(resize_image)
        self.can.create_image(0, 0, image=self.image_tk, anchor='center')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-18
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 2023-02-02
    相关资源
    最近更新 更多