I am trying to create a user interface with a picture in its top right corner. Here is my code:
import tkinter as tk
import urllib.request
import base64 as b64
class my_ui(tk.Tk):
def __init__(self, parent):
tk.Tk.__init__(self,parent)
self.parent=parent
self.intialize()
def intialize(self):
self.grid()
#Welcome
label = tk.Label(self,text="Welcome to my UI", anchor='center',fg='white',bg='blue')
label.grid(column=0,row=0,columnspan=2,rowspan=2,sticky='EW')
#Buttons
button = tk.Button(self,text="Button 1",command=self.OnButtonClick)
button.grid(column=0,row=3,sticky='W')
def OnButtonClick(self):
print("You clicked the button!")
if __name__ == "__main__":
app = my_ui(None)
#Logo URL - just a smiley face
URL = "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcQCItlNQe0QaiuhkADUwgVTpx-Isaym6RAP06PHkzBe2Yza3a4rYIkHuB8"
u = urllib.request.urlopen(URL)
raw_data = u.read()
u.close()
b64_data = b64.encodestring(raw_data)
photo = tk.PhotoImage(data=b64_data)
logo = tk.Label(app, image=photo)
logo.image = photo # To save it in memory
logo.pack() # If I exclude this line, UI works fine.
app.title('My User Interface')
app.mainloop()
I am pulling a .gif from the web and returning a PhotoImage with my function. When I run this, I get no errors - rather, my tkinter window does not appear whatsoever. When I take out the line I mentioned in the comment, my UI comes up fine (buttons, but no image) with no errors.
I am unsure of what exactly the absence of the window means. I am running Python 3.4.1 on Mac OSx. Any help would be greatly appreciated!
When a tk.PhotoImage object gets garbage collected, the image is "released", so to speak. The image is still technically being used, so it's not destroyed, but it will get completely blanked out. Replace your return line with:
photo = tk.PhotoImage(data=b64_data)
return photo
Just be sure to declare photo as a global variable.
Related
So I need to get an image of mine on a button that I've created in python. But it pops up with the error (widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: image "pyimage2" doesn't exist. Also, I've made the main window of my program in a function. Then I've made it so when python has gone through that function it then opens up this startup window, where you can like login and access the LifeLoginWindow. But when I get rid of this startup and just call the LifeLoginWindow function, it runs perfectly and I can see the images. So I don't know what going on. Here is my code :
from tkinter import*
def hello():
print("Works, and hello!")
def LifeLoginWindow():
window = Tk()
TrendsButton = PhotoImage(file = "Trends_Button.png")
TrendsButton_label = Button(SideBar, image = TrendsButton, command = hello)
TrendsButton_label.pack(side=TOP)
SideBar.pack(side = LEFT, fill = Y)
window.mainloop()
StartUp = Tk()
def LoginFunction():
StartUp.destroy
LifeLoginWindow()
StartUpIcon = PhotoImage(file = "Life Login Image Resized.png")
StartUpIcon_label = Label(StartUp, image = StartUpIcon)
StartUpIcon_label.grid(row = 0, column = 2)
LoginButt = Button(StartUp, text = "Login", command = LoginFunction)
LoginButt.grid(row = 3, column = 2)
print("_Loaded Start Up...")
StartUp.mainloop()
You need to keep a reference:
When a PhotoImage object is garbage-collected by Python (e.g. when you return from a function which stored an image in a local variable), the image is cleared even if it’s being displayed by a Tkinter widget.
To avoid this, the program must keep an extra reference to the image object. A simple way to do this is to assign the image to a widget attribute, like this:
label = Label(image=photo)
label.image = photo # keep a reference!
label.pack()
See this page for more on Tkinter PhotoImage.
I have loaded an image to tkinter label and that image is diplayed in that label.When i press the button i need to change that image.When the button is pressed older image is gone but the new image is not displayed
My code is
import Tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
def change_pic(labelname):
photo1 = ImageTk.PhotoImage(Image.open("demo.jpg"))
labelname.configure(image=photo1)
print "updated"
vlabel=tk.Label(root)
photo = ImageTk.PhotoImage(Image.open('cardframe.jpg'))
vlabel.configure(image=photo)
vlabel.pack()
b2=tk.Button(root,text="Capture",command=lambda:change_pic(vlabel))
b2.pack()
root.mainloop()
In def change_pic(labelname), you need to add labelname.photo = photo1 to make sure photo1 not being garbage collected.
def change_pic(labelname):
photo1 = ImageTk.PhotoImage(Image.open("demo.jpg"))
labelname.configure(image=photo1)
labelname.photo = photo1
print "updated"
P.S. Looks like both labelname.photo = photo1 and labelname.image = photo1 work.
Check this out for more details: http://effbot.org/tkinterbook/label.htm
You can use the label to display PhotoImage and BitmapImage objects.
When doing this, make sure you keep a reference to the image object,
to prevent it from being garbage collected by Python’s memory
allocator. You can use a global variable or an instance attribute, or
easier, just add an attribute to the widget instance.
The following edits were made:
I have organised your code layout and simplified its
syntax where possible. These are to make your code easier to read.
Commonly we make the PIL objects a subset/children of tk.
So long it is a part of root (i.e. it is a child of the root
or any of its child widgets), your PIL objects will work.
Your working code is shown below:
import Tkinter as tk
from PIL import Image, ImageTk
def change_pic():
vlabel.configure(image=root.photo1)
print "updated"
root = tk.Tk()
photo = 'cardframe.jpg'
photo1 = "demo.jpg"
root.photo = ImageTk.PhotoImage(Image.open(photo))
root.photo1 = ImageTk.PhotoImage(Image.open(photo1))
vlabel=tk.Label(root,image=root.photo)
vlabel.pack()
b2=tk.Button(root,text="Capture",command=change_pic)
b2.pack()
root.mainloop()
I got it working with one more line of code:
import tkinter as tk # I am using python 3 on windows so the tkinter is lowercased
from PIL import Image, ImageTk
root = tk.Tk()
def change_pic(labelname):
global photo1 # This is the only new line you need, I believe
photo1 = ImageTk.PhotoImage(Image.open("demo.jpg"))
labelname.configure(image=photo1)
print("updated") # Again I'm using python 3 on windows so syntax may differ.
root.update() # You don't need this statement in this case, but it never hurts
vlabel=tk.Label(root)
photo = ImageTk.PhotoImage(Image.open('cardframe.jpg'))
vlabel.configure(image=photo)
vlabel.pack()
b2=tk.Button(root,text="Capture",command=lambda:change_pic(vlabel))
b2.pack()
root.mainloop()
I believe that the code changes the image locally, so the global statement will change it on the project scope.
I am a newbie to python.I have a code where the image is not printed on the Tkinter.So please help me on how to display the image along with the Button and Textbox.
Code:
import Tkinter
from Tkinter import *
class myproject(Tkinter.Tk):
def __init__(self,parent):
Tkinter.Tk.__init__(self)
self.button2()
self.text()
self.image()
def button2(self):
button2 = Tkinter.Button(self, text = "hello")
button2.grid(column=5,row=7)
def text(self):
text = Tkinter.Text(self, height=3, width=31) # self.text
text.grid(column=1,row=3)
text.insert(END, "Wiilliam Skakespeare")
def image(self):
logo = PhotoImage(file="linux.gif")
w1 = Tkinter.Label(self, image=logo).pack(side="right")
app = myproject(None)
app.mainloop()
Please help!Answers will be appreciated!
You have to save a reference to the photo image.
See this page for more information, or this one
There are numerous other problems with the code you posted, however; you need colons after function and class declarations, for example. When posting code, there's also no need for extraneous methods in the class, they only make it more difficult to understand
You also cannot mix managers or you're whole program might stall. This means you shouldn't be using pack and grid in the same program. Read through the effbot tutorial, it's really helpful!
class myproject(Tkinter.Tk):
def __init__(self,parent):
Tkinter.Tk.__init__(self)
self.image()
def image(self):
logo = Tkinter.PhotoImage(file='linux.gif')
self.logo = logo # You always need a reference to the image or it gets garbage collected
w1 = Tkinter.Label(self, image=logo).grid()
app = myproject(None)
app.mainloop()
I have very strange problem with gtk.Image(). Simple question; how to update image?
On window creation I create image and pack it… On that time I load image from disk. Now I start downloading image from url, and when it's done I just want to replace existing image with new one. I rewrite content of same file on disk and then do:
pixbuf = gtk.gdk.pixbuf_new_from_file(image_path)
self._user_avatar.set_from_pixbuf(pixbuf)
I have tried
self._user_avatar.set_from_file(image_path)
and
self._user_avatar.clear()
nothing works. When i restart app there is a new image and everything is ok.
gtk.Image.set_from_pixbuf is the right method, so your problem may come from something else. Try on the most simple piece of code to reproduce your problem.
Here's a working sample:
import pygtk
pygtk.require('2.0')
import gtk
pics = []
clicks = 0
def on_destroy (widget):
gtk.main_quit()
return False
def on_button_clicked (widget, image):
global clicks
clicks += 1
image.set_from_pixbuf (pics[clicks % len(pics)])
def create ():
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.connect("destroy", on_destroy)
pics.append (gtk.gdk.pixbuf_new_from_file("sample1.png"))
pics.append (gtk.gdk.pixbuf_new_from_file("sample2.png"))
image = gtk.Image()
image.set_from_pixbuf(pics[0])
button = gtk.Button ("Switch Image")
button.connect("clicked", on_button_clicked, image)
vbox = gtk.VBox()
vbox.pack_start (image)
vbox.pack_start (button)
window.add(vbox)
window.show_all()
if __name__ == "__main__":
create()
gtk.main()
I'm building a small educational app.
I already have all the code done, all I'm missing is a way is getting a window to open with TK displaying a textbox, an image and a button.
All it should do, it return the text inserted in the textbox after clicking the button and closing the windows.
So, how do I do this?
I have been looking at code, but nothing I did worked, I almost fell ashamed being this so basic.
Thanks
An easy way to write GUIs is using Tkinter. There's an example that display a windows with a text and a button:
from Tkinter import*
class GUI:
def __init__(self,v):
self.entry = Entry(v)
self.entry.pack()
self.button=Button(v, text="Press the button",command=self.pressButton)
self.button.pack()
self.t = StringVar()
self.t.set("You wrote: ")
self.label=Label(v, textvariable=self.t)
self.label.pack()
self.n = 0
def pressButton(self):
text = self.entry.get()
self.t.set("You wrote: "+text)
w=Tk()
gui=GUI(w)
w.mainloop()
You may look at the Tkinter documentation, the label widget also supports to include pictures.
Regards
This is a simple code that get the input from the inputBox to myText. It should get you started on the right direction. Depending on what else you need to check or do, you can add more functions to it. Notice you might have to play around with the order of the line image = tk.PhotoImage(data=b64_data). Because if you put it right after b64_data = .... It will gives you error. (I am running MAC 10.6 with Python 3.2). And the picture only works with GIF at the moment. See reference at the bottom if you want to learn more.
import tkinter as tk
import urllib.request
import base64
# Download the image using urllib
URL = "http://www.contentmanagement365.com/Content/Exhibition6/Files/369a0147-0853-4bb0-85ff-c1beda37c3db/apple_logo_50x50.gif"
u = urllib.request.urlopen(URL)
raw_data = u.read()
u.close()
b64_data = base64.encodestring(raw_data)
# The string you want to returned is somewhere outside
myText = 'empty'
def getText():
global myText
# You can perform check on some condition if you want to
# If it is okay, then store the value, and exist
myText = inputBox.get()
print('User Entered:', myText)
root.destroy()
root = tk.Tk()
# Just a simple title
simpleTitle = tk.Label(root)
simpleTitle['text'] = 'Please enter your input here'
simpleTitle.pack()
# The image (but in the label widget)
image = tk.PhotoImage(data=b64_data)
imageLabel = tk.Label(image=image)
imageLabel.pack()
# The entry box widget
inputBox = tk.Entry(root)
inputBox.pack()
# The button widget
button = tk.Button(root, text='Submit', command=getText)
button.pack()
tk.mainloop()
Here is the reference if you want to know more about the Tkinter Entry Widget: http://effbot.org/tkinterbook/entry.htm
Reference on how to get the image: Stackoverflow Question