Почему не выводится фотография в дочернем окне tkinter?

Рейтинг: 1Ответов: 1Опубликовано: 15.02.2023

Вот мой код:

import tkinter
from tkinter import *
import tkinter as tk
from tkinter import ttk
from PIL import ImageTk, Image
    
    
def Help():
    def Destroy():
        window.destroy()   

    window=tk.Tk()
    window.title("Новое окно")
    window.geometry("300x180")
    
    label = ttk.Label(window, text="Высота", foreground='black',
                       font='Arial 10').place(relx=0.5, rely=0.5, anchor="c") 

    submit = Button(window, text='Cancel',
                     command=Destroy).place(relx=0.8, rely=0.8, anchor="c", width=70, height=30) 

    ph=Image.open('pop.png')
    ph=ph.resize((300,300), Image.LANCZOS)
    ph=ImageTk.PhotoImage(ph)
    ph=Label(window, image=ph)
    ph.image=ph
    ph.place(x=10, y=10)


def OK():
    p = entry1.get()
    print(p)
    entry1.delete(0, END)
    entry2.delete(0, END)
    entry2.insert(0,p)


def Cancel():
    root.destroy()


root = Tk()
root.title("Параметры стандартной атмосферы")
root.geometry("700x400")
root.resizable(False, False)

label1 = ttk.Label(text="Высота", foreground='black',
                   font='Arial 10').place(relx=0.6, rely=0.1, anchor="c")
label2 = ttk.Label(text="Поле ввода высоты", foreground='black',
                   font='Arial 10').place(relx=0.1, rely=0.2, anchor="c")
label3 = ttk.Label(text="Давление", foreground='black',
                   font='Arial 10').place(relx=0.2, rely=0.6, anchor="c")
label4 = ttk.Label(text="Плотность", foreground='black',
                   font='Arial 10').place(relx=0.4, rely=0.6, anchor="c")
label5 = ttk.Label(text="Температура", foreground='black',
                   font='Arial 10').place(relx=0.6, rely=0.6, anchor="c")
label6 = ttk.Label(text="Скорость звука", foreground='black',
                   font='Arial 10').place(relx=0.8, rely=0.6, anchor="c")

entry1 = ttk.Entry()
entry1.place(relx=0.75, rely=0.1, anchor="c")
entry2 = ttk.Entry()
entry2.place(relx=0.3, rely=0.2, anchor="c")
entry3 = ttk.Entry().place(relx=0.2, rely=0.5, anchor="c")
entry4 = ttk.Entry().place(relx=0.4, rely=0.5, anchor="c")
entry5 = ttk.Entry().place(relx=0.6, rely=0.5, anchor="c")
entry6 = ttk.Entry().place(relx=0.8, rely=0.5, anchor="c")

submit1 = Button(root, text='Cancel',
                 command=Cancel).place(relx=0.2, rely=0.8, anchor="c", width=70, height=30)
submit2 = Button(root, text='Help',
                 command=Help).place(relx=0.5, rely=0.8, anchor="c", width=70, height=30)
submit3 = Button(root, text='OK',
                 command=OK).place(relx=0.7, rely=0.8, anchor="c", width=70, height=30)

root.mainloop()

Выдаёт ошибку:

image «pyimage1» doesn't exist.

Ответы

▲ 1Принят

Проблема заключается в том, как вы создаете и воспроизводите метку изображения в дочернем окне. Вам нужно убедиться, что объект "Photo Image" не уничтожен сборщиком мусора, что может произойти, когда он выходит за пределы области видимости.

Вот измененная функция Help, которая должна устранить проблему:

def Help():
    def Destroy():
        window.destroy()

    window = Toplevel(root)
    window.title("Новое окно")
    window.geometry("300x300")

    label = ttk.Label(window, text="Высота", foreground='black',
                      font='Arial 10').place(relx=0.5, rely=0.5, anchor="c")

    ph = Image.open('pop.png')
    ph = ph.resize((200, 200), Image.LANCZOS)
    ph = ImageTk.PhotoImage(ph)
    ph_label = Label(window, image=ph)
    ph_label.image = ph  # сохранение ссылки на изображение
    ph_label.place(x=50, y=50)

    submit = Button(window, text='Cancel',
                    command=Destroy).place(relx=0.8, rely=0.8, anchor="c", width=70, height=30)

Что изменилось:

  1. Мы создаем дочернее окно, используя верхний уровень вместо Tk (TopLevel);
  2. Мы создаем объект "PhotoImage" и метку изображения ph_label отдельно;
  3. Мы сохраняем ссылку на изображение, используя ph_label.image = photo;
  4. Мы помещаем метку изображения в окно, используя ph_label.place().

Это должно предотвратить уничтожение объекта "PhotoImage" и позволить отображаться изображению в дочернем окне. При необходимости можете вернуть значения размера окна, ресайза и расположения изображения обратно на свои.