I have been stuck trying to add an image to my tkinter GUI and google does not seem to give answers. I understand that I should not use grid or pack gemoetry managers within the same master window, and I havent as far as I can tell but every attempt has resulted in either of the following error messages:
TclError: cannot use geometry manager grid inside . which already has slaves managed by pack
or:
TclError: image "pyimage86" doesn't exist
Incidently everytime I rerun my code the "pyimage86" changes, every run increases the number by 1, for example 'pyimage86', 'pyimage87', etc etc.
The first error message is particularly confusing because I am using .grid to place my labelled image into the class but the error is saying otherwise? (example code is not in a class, I know)
I have tried different images and converted the original image into a .TIF, .JNP, .PNG, .GIF but none give a result. I have also removed the Alpha channel (apprantly that might have been an issue when using ImageTK.PhotoImage but it did not help). I have also converted the image into grasyscale as a last ditch attempt but no luck.
import tkinter as tk
import PIL.Image
import PIL.ImageTk
root = tk.Tk()
image = Image.open("TemplateRack_GUI.png")
photo = ImageTk.PhotoImage(image)
label = tk.Label(image=photo)
label.image = photo
label.grid(row=5, column=5)
root.mainloop()
You say that your program gives you sometimes:
TclError: cannot use geometry manager grid inside which already has slaves managed by pack.
and sometimes:
TclError: image "pyimage86" doesn't exist.
I can't believe that!
Furthermore you said "I understand that I should not use grid or pack gemoetry managers within the same class"
About which class are you talking?
Tkinter docs says: Never mix grid and pack in the same master window.
Please check your code again because you are using somewhere pack and grid.
Related
I was wondering if there is anyway to get the ico file of one window and use it in the same window, without getting to know the icon location.
from tkinter import *
root = Tk()
root.iconbitmap('img/icn.ico')
top = Toplevel()
root.mainloop()
Here I want top to have icon of root without saying top.iconbitmap() or top.iconphoto(), the closest ive got is top.tk.call('wm','iconbitmap') but I dont know what is to be done with this as i couldnt find a understandable documentation.
Why dont I want to use iconbitmap(), its basically that, with tkinter.messagebox you can see the messagebox automatically inherit the icons from the parent widget. I was trying to duplicate this effect. Where if the icon is the default tk icon, then show blank icon or else show the custom icon.
Thanks in advance :D
[I'm using links into the core Tk documentation here. It's much more accurate than the Tkinter docs for most things, and Tkinter is mostly an obvious thin wrapper around it.]
You don't want wm iconbitmap. That's been effectively obsolete for decades; it uses an object class — bitmap — that's not relevant these days as it is monochrome and uses the weirdest format. (Filenames need to be preceded by # to make them work.)
Instead, you want to manipulate the wm iconphoto of the toplevel windows concerned. These take true photo images (there are many image file formats you can load into them) and you can share them easily.
# Load the image from the file; can also use PNG and other formats
my_image = PhotoImage(file="image.gif")
# Apply the image as the icons
first_toplevel_window.iconphoto(False, my_image)
second_toplevel_window.iconphoto(False, my_image)
Note that how the icon is displayed can vary wildly; it's not under your control.
You can use iconphoto() and set the first argument to True, then the same icon will be used for future created toplevels as well:
import tkinter as tk
root = tk.Tk()
icn = tk.PhotoImage(file='my-icon.png')
root.iconphoto(True, icn)
top = tk.Toplevel(root)
root.mainloop()
If you use the default instead of the bitmap (or first) argument, the icon will automatically be used on all TopLevel windows:
root.iconbitmap('img/icn.ico') # icon set only on root
root.iconbitmap(bitmap='img/icn.ico') # same as above
root.iconbitmap(default='img/icn.ico') # icon set on root and all TopLevels
I cannot start my Python program. I've a problem that I cannot open a .gif file, and I cannot figure out how!
I keep getting a long error message:
"RuntimeError: Too early to create image"
I have moved the gif files into the same project file as the code, and I tried looking online, but everyone uses different packages, and I just cannot find a way around it. I also have the gifs open on pycharm.
Here is my code:
import random
from tkinter import *
sign = random.randint(0, 1)
if (sign == 1):
photo = PhotoImage(file="X.gif")
else:
photo = PhotoImage(file="O.gif")
My overall goal is to show an image like a finished tic tac toe game, with randomly placed X's and O's, and there does not have to be any specific order like 3 in a row. Here is the homework problem:
Display a frame that contains nine labels. A label may display an image icon for X or an image icon for O, as shown in Figure 12.27c. What to display is randomly decided.
Use the Math.random() method to generate an integer 0 or 1, which corresponds to displaying an X or O image icon. These images are in the files x.gif and o.gif.
I can see from the code that you're using PhotoImage before creating a main window gives you an Runtime error and it is clearly said in the error that "Too early to create image" means the image cannot be create if there is no active Tk window.
The reason why some people prefer the use other module because it give you more flexibility to resize, reshape, invert and more. ( By the way it could Pillow module from PIL import Image, ImageTk How to use PIL in Tkinter ).
Now back to your code.
You can randomise "O" and "X" images without even use of if-else.
I created main window before creating the Image.
Make sure the images you using are in the same directory.
import random
from tkinter import *
sign = random.choice( ["X.gif", "O.gif"] )
print(sign,"photo has been selected")
root = Tk()
Photo = PhotoImage(file=sign)
display_photo = Label(root, image=Photo)
display_photo.pack()
mainloop()
Currently I'm using this snippet of code which seems pretty easy:
label = ttk.Label(mainframe)
image1 = PhotoImage(file='my_image.gif')
label['image'] = image1
label.grid(column=1, row=0)
However, if I edit the size of my_image.gif in photoshop, then run it again, the image gets stretched to the same size, and this seems to continue no matter how small I make the base image. This seems to suggest to me that the PhotoImage or something above it enforces a default size or specific minimum size. I cannot find any documentation to suggest that this is the case.
From here I found the help(PhotoImage) suggestion which I used. When in the python interpreter I run the help(PhotoImage) command and I found this:
height(self)
Return the height of the image.
type(self)
Return the type of the imgage, e.g. "photo" or "bitmap".
width(self)
Return the width of the image.
But it doesn't seem to provide me with an image sizing of any type either.
After searching all over and seeing no reference at all, i'm beginning to suspect that using images in a Label is for a specific purpose and I'm approaching this all wrong. All i'm trying to do is place a logo at the top of the window, but I want the logo to be limited in size so it doesn't take over the whole window.
Also of note is this question which seems to be lacking an answer but I too am curious if there is some documentation on it. Maybe I'm missing something obvious but I did check the python documentation and the http://www.tkdocs.com site for more information.
Apparently I made an error, but I have no clue what it was. In the end this was this code that did it for me:
from tkinter import *
from tkinter import ttk
root = Tk()
root.title("ImageTest")
label = ttk.Label(root)
image1 = PhotoImage(file='my_image.gif')
label['image'] = image1
label.grid(column=1, row=0)
root.mainloop()
It's all working now as expected.
I've been tinkering around with Python lately and wanted to make a GUI that reads from a CSV and displays it correctly.
CSV build up:
name,description,image location
steven,some guy,/res/pic/steven.gif
the first two entries should be put in text labels, and the last entry should be used as an image.
In my code I got as far as inserting the picture, which worked. But as soon as I also embedded the text label, I think the application runs into an infinity loop.
If I delete the Image from the code, the text label works and vice versa.
from Tkinter import *
from PIL import *
import os
import csv
#Functions
def insertImage(guiName,picture,x,y):
#This is the Image label insertion, delete it and Text label works
img = PhotoImage(file=entryList[picture][2])
preview = Label(guiName, image=img)
preview.img = img
preview.grid(row=x,column=y)
#This is the Text label insertion, delete it and Image Label works
Name = StringVar()
labelName = Label(mainGUI, textvariable=Name, justify=LEFT)
Name.set(entryList[picture][2])
labelName.pack()
global mainGUI
mainGUI = Tk()
mainGUI.geometry("500x500")
mainGUI.title('Index')
reader = csv.reader(open("res/test.csv", "rb"))
entryList = []
for row in reader:
entryList.append( row )
#insertImage(mainGUI,entryList[1][2],1,1)
insertImage(mainGUI,1,1,1)
#insertImage(mainGUI,2,2,1)
mainGUI.mainloop()
Does anyone have an idea what the problem might be?
The problem is that you are using grid() and pack() to position widgets within the same master widget (mainGUI). That won't work, because by default both of those geometry managers attempt to manage the size of the parent widget and end up fighting over the size (which blocks the GUI from ever appearing as a side effect).
The very latest version of Tk (the lib underneath Tkinter) will throw an error if you try to do this (finally!) but your best bet is to just use one geometry manager per parent widget. (There are some subtleties with disabling geometry propagation which can make this work, and “parent” can be a touch tricky in a few situations, but the key issue is that you're doing the wrong thing in the first place.)
Also, a single label can contain both an image and some text; see the compound option (which enables this and controls the relative placement rules).
I'm missing something at a very basic level when it comes to loading an image using PIL and displaying it in a window created by Tkinter. The simplest form of what I'm trying to do is:
import Tkinter as TK
from PIL import Image, ImageTk
im = Image.open("C:\\tinycat.jpg")
tkIm = ImageTk.PhotoImage(im)
tkIm.pack()
TK.mainloop()
When I try to run the code above, I get the following:
RuntimeError: Too early to create image
Exception AttributeError: "PhotoImage instance has no attribute
'_PhotoImage__photo'" in <bound method PhotoImage.__del__ of
<PIL.ImageTk.PhotoImage instance at 0x00C00030>> ignored
I've confirmed the file is present and can be opened in an image editor and also that it can be displayed using im.show(). What am I missing?
Tkinter has to be instantiated before you call ImageTk.PhotoImage():
TK.Tk()
It's very true what Meredith said you need to add that line for sure!
I would like to show you my image formatting and then compare it to yours and see if there any different, my code for a image is
master.image = PhotoImage(file="Banditlogo.gif")
w = Label(master, image=master.image)
w.photo = master
w.pack()
And your code is
im = Image.open("C:\\tinycat.jpg")
tkIm = ImageTk.PhotoImage(im)
tkIm.pack()
We are both using PIL with PhotoImage
I can't help wondering are both ways correct?
At this point in time I don't have enough knowledge to fully answer your PIL question but it is interesting to compare both codes as they are different. I can only suggest doing what I do when it comes to example codes people share with me, and that is "if mine don't work, try the example code and see if that fixes the code" when I find something that works I stick with it.
Would someone with more understanding of Tkinter please explane the workings of, How do I use PIL with Tkinter?
Knowledge is power so please share.