Reputation: 5745
I am building an application to continuously display an image fetched from an IP camera. I have figured out how to fetch the image, and how to also display the image using Tkinter. But I cannot get it to continuously refresh the image. Using Python 2.7+.
Here is the code I have so far.
import urllib2, base64
from PIL import Image,ImageTk
import StringIO
import Tkinter
URL = 'http://myurl.cgi'
USERNAME = 'myusername'
PASSWORD = 'mypassword'
def fetch_image(url,username,password):
# this code works fine
request = urllib2.Request(url)
base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
request.add_header("Authorization", "Basic %s" % base64string)
result = urllib2.urlopen(request)
imgresp = result.read()
img = Image.open(StringIO.StringIO(imgresp))
return img
root = Tkinter.Tk()
img = fetch_image(URL,USERNAME,PASSWORD)
tkimg = ImageTk.PhotoImage(img)
Tkinter.Label(root,image=tkimg).pack()
root.mainloop()
How should I edit the code so that the fetch_image
is called repeatedly and its output updated in the Tkinter window?
Note that I am not using any button-events to trigger the image refresh, rather it should be refreshed automatically, say, every 1 second.
Upvotes: 1
Views: 8689
Reputation: 14098
Here is a solution that uses Tkinter's Tk.after
function, which schedules future calls to functions. If you replace everything after your fetch_image
definition with the snipped below, you'll get the behavior you described:
root = Tkinter.Tk()
label = Tkinter.Label(root)
label.pack()
img = None
tkimg = [None] # This, or something like it, is necessary because if you do not keep a reference to PhotoImage instances, they get garbage collected.
delay = 500 # in milliseconds
def loopCapture():
print "capturing"
# img = fetch_image(URL,USERNAME,PASSWORD)
img = Image.new('1', (100, 100), 0)
tkimg[0] = ImageTk.PhotoImage(img)
label.config(image=tkimg[0])
root.update_idletasks()
root.after(delay, loopCapture)
loopCapture()
root.mainloop()
Upvotes: 2