0

我正在尝试开发一个程序,它有一个主框架(根),其他框架通过菜单打开和关闭。主框架的图像插入正常,但是一旦我打开另一个框架并尝试使用以下方法插入新图像:

    canvas = Canvas(date-time_window, width = 200, height = 200, bg = 'yellow') 
canvas.create_image(0, 0, image = moon_photo, anchor = NW)

我得到一个错误 pyimage2 不存在,但是如果我删除对框架的引用:

    canvas = Canvas(width = 200, height = 200, bg = 'yellow')

图像可以出现在根框架中,但当然不是我想要的那个。

是否可以一次显示超过一帧的图像?

我还注意到,如果我关闭主框架然后重新打开它而不完全重新启动,我会得到与主框架中显示的图像相同的错误。我再次得到 pyimage2 不存在加上根框架中的画布是空白的。

我已经阅读了关于 tkinter 如何处理垃圾的评论,并怀疑这可能是相关的。我还阅读了一条评论,说图像应该附加第二个参考,但还没有看到如何实现这个动作。

这可以在 tkinter 中完成,还是我需要考虑使用枕头来代替?

示例代码,包含原始代码。

该代码是从根窗口中的菜单调用的,旨在显示本地日期和时间信息。我试图获取当前月相的图片,包括:

def date_time():
    date_time_window = Tk()
    date_time_window.title('Date & Time')
    date_time_window.geometry('650x350')

    # Widgets

    present_date = today

    main_heading = Label(date_time_window, text = 'Date & Time')
    line1 = Canvas(date_time_window, width = 650, height = 3)
    line1.create_line(0,2 , 650,2, width = 1, fill = 'cyan')
    date_txt = Label(date_time_window,text = 'Date: ')
    date_value = Label(date_time_window, text =  today.strftime('%d') + '/' +       today.strftime('%m') + '/' + today.strftime('%y'))
    time_utc_txt = Label(date_time_window, text = 'UTC Time:')
    time_utc_value = Label(date_time_window, text = str(datetime.utcnow())[11:19])
    dls_txt = Label(date_time_window, text = 'DLS on/off: ')

    if moon_phase_number == 0:
        moon_photo = PhotoImage( file = 'images\moon_phase_0.gif')
    elif moon_phase_number == 1:
        moon_photo = PhotoImage( file = 'images\moon_phase_1.gif')


    canvas = Canvas(date_time_window, width = 200, height = 200, bg = 'yellow')        
    canvas.create_image(0, 0, image = moon_photo, anchor = NW)

    canvas.place( x = 300, y = 150)

    close_btn.configure( command = date_time_window.destroy)

    date_time_window.mainloop()
4

1 回答 1

1

如果没有 SSCCE,我无法调试给出的代码示例,但我会尝试令人满意地回答您剩余的问题。


是否可以一次显示超过一帧的图像?

是的,对可能包含图像的帧数没有特别限制。


我还阅读了一条评论,说图像应该附加第二个参考,但还没有看到如何实现这个动作。

该评论可能参考了这份文件:

注意:当 Python 对 PhotoImage 对象进行垃圾收集时(例如,当您从将图像存储在局部变量中的函数返回时),即使 Tkinter 小部件正在显示该图像,它也会被清除。

为避免这种情况,程序必须保留对图像对象的额外引用。一种简单的方法是将图像分配给小部件属性,如下所示:

label = Label(image=photo)
label.image = photo # keep a reference!
label.pack()

同样,您应该附加moon_photo到您的小部件之一。canvas.image = moonphoto就足够了。


这可以在 tkinter 中完成,还是我需要考虑使用枕头来代替?

人们一般推荐 PIL/Pillow 用于显示图像,因为 PhotoImage 只能显示 gif 和 pgm 图像。PIL 的ImageTk.PhotoImage类支持更多种类的格式。然而,由于你只是想在这里渲染 gif,你不需要 Tkinter 以外的任何东西。

于 2014-06-26T14:56:52.337 回答