-1

I am new to python and trying to make a Tkinter label which would change its image at run time. Here is my code:

from Tkinter import *
from PIL import ImageTk, Image
import os
import time
#time.sleep(1)

class projector:

  def __init__(self):
     self.root = Tk()
     self.frame = Frame(self.root)
     self.label = Label(self.frame )
     self.number = 1


  def callback(self,e):       
     self.changeimage()


  def check(self):
     scr_height = self.root.winfo_screenheight()
     scr_width  = self.root.winfo_screenwidth()
     image_src = "img/pattern/1.png"
     im_temp = Image.open(image_src)
     im_temp = im_temp.resize((scr_width, scr_height), Image.ANTIALIAS)
     im_temp.save("ArtWrk.ppm", "ppm")
     photo = PhotoImage(file="artwrk.ppm")
     self.label.configure(image=photo)
     self.label.pack()
     self.frame.pack()    
     self.root.bind("<Return>", self.callback)
     self.root.geometry("{0}x{1}+0+0".format(scr_width, scr_height))
     #self.root.overrideredirect('true')
     self.root.mainloop()

  def nextpattern(self):
     abc=''

  def changeimage(self):
      self.number= self.number+1;
      path = "img/pattern/"+str(self.number)+".png"
      self.image = ImageTk.PhotoImage(Image.open(path))
      self.label.config(image = self.image)
      print "loaded image "+ str(self.number)

 def main():
 projector().check()

 if __name__ == "__main__":
    main()

it works well if changeimage() method is attached to event listener and give sequence of images when enter is pressed. But when I try to change the label image using a loop it just shows me last image. Any suggestions how I can use changeimage() im loop ?? Help would be really appriciated.

Hamza Tasneem
  • 74
  • 3
  • 12

1 Answers1

1

when you use self.root.mainloop() it creates it's own event loop, part of which is to update the GUI. Any callback that updates the GUI multiple times will run before the application updates, unless explicitly updated (reference to methods, use either .update() or .update_idle_tasks())

for i in range(10):
    self.changeimage()
    self.root.update_idle_tasks()

How ever this makes the images flash so quickly that it will probably get to the end before you even open the window, you could add time.sleep but that locks your application for the time since it cannot resume the mainloop, so your best bet is definitely to use the .after method.

Requests Tkinter to call function callback with arguments args after a delay of at least delay_ms milliseconds. There is no upper limit to how long it will actually take, but your callback won't be called sooner than you request, and it will be called only once.

so to call self.changeimage after 1000 ms (1 second) you would use:

self.root.after(1000, self.changeimage)

you would probably call this once (or just self.changeimage()) at the beginning of your program (initialization) and then at the end of self.changeimage to schedule the next change, also note that if you need to cancel the delay (reset if the user presses ) it covers that too:

This method returns an integer “after identifier” that can be passed to the .after_cancel() method if you want to cancel the callback.

Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59
  • well the update() function did the job for me as I only wanted static images to be placed there.... thankyou. The answer was really helpfull........ – Hamza Tasneem May 11 '16 at 20:29