如何将图像插入到tkinter子帧中

时间:2014-06-26 13:19:06

标签: python-3.x tkinter photoimage

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

    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()

1 个答案:

答案 0 :(得分:1)

我无法调试没有SSCCE的代码示例,但我会尝试令人满意地回答你剩下的问题。


  

是否可以一次显示多个帧中的图像?

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


  

我还阅读了一条评论,说明图片应附有第二个参考,但尚未看到如何实施此操作。

该评论可能参考了this文件:

  

注意:当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之外你不需要任何东西。