Изображение Tkinter не отображается при рендеринге объектов класса с несколькими кадрами - PullRequest
0 голосов
/ 19 апреля 2020

Я создал настольное приложение с использованием Tkinter в python3. Для приложения существует объект основного класса «Стек», и внутри него есть функция для отображения нескольких кадров для навигации к другим windows в приложении по событию нажатия кнопки.

Я пытаюсь отобразить изображение на экране «Домашняя страница» (и фактически все страницы в качестве заголовка), используя PIL.ImageTk / PIL.Image. Каждый раз, когда я запускаю приложение из терминала (macOS), приложение для настольного компьютера запускается, но изображение не появляется. Что я делаю неправильно? Вот мой код:


import getpass
import tkinter as tk
from tkinter import ttk
from PIL import ImageTk, Image

LARGE_FONT = ('Source Code Pro', 24)

class Stack(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)

        container = tk.Frame(self)
        container.pack(side='top', fill='both', expand=True)

        container.grid_rowconfigure(0, weight=1) 
        container.grid_columnconfigure(0, weight=1) 

        self.frames = {}

        for F in (HomePage, NdA):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky='news')
        self.show_frame(HomePage)

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()

class HomePage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        username = getpass.getuser()
        logo_path = 'myfilepath'.format(username)
        img = ImageTk.PhotoImage(Image.open(logo_path+'myimage.png').resize((120,120)))
        l = tk.Label(self, image=img)
        l.grid(column=0, row=0, ipadx=10, ipady=5, sticky='w')
        ttk.Label(
            self, 
            text='Some Text',
            wraplength=450,
            justify=tk.LEFT
            ).grid(
                column=1, 
                row=0,
                ipady=10,
                padx=(0,10),  
                sticky='nw')

        tier1 = tk.Button(self, text='Button1', state=tk.DISABLED).grid(column=0, row=3, padx=10, columnspan=2, sticky='nesw')
        tier2 = tk.Button(self, text='Button2', state=tk.DISABLED).grid(column=0, row=4, padx=10, columnspan=4, sticky='nesw')
        tier3 = ttk.Button(self, text='Button3', command=lambda: controller.show_frame(Tier3))
        tier3.grid(column=0, row=5, padx=10, columnspan=4, sticky='nesw')

        nda = ttk.Button(self, text='Button4', command=lambda: controller.show_frame(NdA))
        nda.grid(column=0, row=6, padx=10, pady=(0,10), columnspan=4, sticky='nesw')

class NdA(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        def clear_form():
            effective_date.delete(0, END)
            client_name.delete(0, END)
            address.delete(0, END)
            user_initials.delete(0, END)

        def submit_data():
            functions.create_nda(
                date=effective_date.get(), 
                client_name=client_name.get(), 
                address=address.get(), 
                user=user_initials.get()
                )
            effective_date.delete(0, tk.END)
            client_name.delete(0, tk.END)
            address.delete(0, tk.END)
            user_initials.delete(0, tk.END)
            messagebox.showinfo('Heading Text', 'Message Text')

        tk.Label(
            self, 
            text='Some Text',
            wraplength=450,
            justify=tk.LEFT
            ).grid(
                column=1, 
                row=0,
                columnspan=3, 
                ipady=10,
                padx=(0,10),  
                sticky='nw')

        tk.Label(self, text='Label1').grid(column=0, row=2, pady=(20,10), columnspan=4, sticky='news')

        tk.Label(self, text='Data1').grid(column=0, row=3, padx=(10,0), sticky='w')
        client_name = tk.Entry(self, width=30)
        client_name.grid(column=1, row=3, columnspan=3, padx=(0,10), sticky='news')

        tk.Label(self, text='Data2').grid(column=0, row=5, padx=(10,0), sticky='w')
        address = tk.Entry(self, width=30)
        address.grid(column=1, row=5, columnspan=3, padx=(0,10), sticky='news')

        tk.Label(self, text='Data3').grid(column=0, row=6, padx=(10,0), sticky='w')
        effective_date = tk.Entry(self, width=30)
        effective_date.insert(1, ' mm/dd/yyyy')
        effective_date.grid(column=1, row=6, columnspan=3, padx=(0,10), sticky='news')

        tk.Label(self, text='Data4').grid(column=0, row=7, padx=(10,0), sticky='w')
        user_initials = tk.Entry(self, width=30)
        user_initials.grid(column=1, row=7, columnspan=3, padx=(0,10), sticky='news')

        create_tier3 = tk.Button(self, text='or click me', command=submit_data).grid(column=3, row=8, pady=(30,10), padx=(0,10), sticky='news')
        clear_form = tk.Button(self, text='click me', command=clear_form).grid(column=2, row=8, pady=(30,10), padx=(5,5), sticky='news')
        # return_home = tk.Button(self, text='HOME').grid(column=1, row=8, pady=(30,10), sticky='news')


app = Stack()
app.mainloop()

1 Ответ

1 голос
/ 20 апреля 2020

Когда функция __init__() в классе HomePage выходит из имени img, происходит сборка мусора, поэтому метка не может его запомнить. Вам необходимо сохранить ссылку на изображение. Обычный способ - сохранить его как атрибут метки:

l = tk.Label(self, image=img)
l.image = img      # Save reference to image
...