Default Image sizes in ttk.Label - python

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.

Related

Unable to understand Tkinter configure

I am reading a script about how to make a small game of dice rolling, and now have a difficulty understanding the last two lines below:
To me, it seems the image was already updated by ".configure(image = DiceImage)"
So why we have to update the image again by the last line "ImageLabel.image = DiceImage"?
ImageLabel = tkinter.Label(root, image = DiceImage)
def rolling_dice():
DiceImage = ImageTk.PhotoImage(Image.open(random.choice(dice)))
ImageLabel.configure(image = DiceImage)
ImageLabel.image = DiceImage
The line ImageLabel.image = DiceImage is not configuring the widget. Tkinter images get destroyed by the garbage collector if a reference isn't saved somewhere. This results in a blank space where the image should be.
Saving it as an attribute to the widget it is associated with is the simplest solution to work around that problem.

Tkinter message wrapping for text unknown reason

I have run into a strange behaviour of Tkinter's Message widget. It worked fine before, but now it is wrapping (Date and time on left image, only date on right image) when it shouldn't. I noticed time wrapped for some seconds and others not, because not all characters are the same length.
Note that the images are cropped, but the widget actually continues about 200 more pixels. I have not set wraplength (which weirdly enough wasn't even recognised as an option, even though it is in the docs) so that is still at its default 0 (no wrapping). I have played around a bunch but I can't figure it out.
The text is generated from a dictionary, roughly as follows:
import tkinter as tk
root = tk.Tk()
root.geometry('500x500+0+0')
root.configure(bg='white')
desc = tk.Message(root)
desc.configure(bg='white')
desc.pack()
description={}
description['Date'] = '11 June 2020'
description['Time'] = '21:26:26'
description['Duration'] = 0
description['Overlay'] = str(False)
descToLines = [f'{key}:\t {val}' for key, val in description.items()]
linesToString = '\n'.join(descToLines)
desc.configure(text=linesToString)
root.mainloop()
In fact, while verifying this minimal code, the time line 21:26:38 is now inline with Time, but the date still isn't. Any help is welcome.
And here is how you can see what is missing: change the background color of the Message box to another color. You'll immediately see that its width is too small. Try:
desc.configure(bg='#FF0000')
And then:
desc.configure(bg='#00FF00', width=200)
Which gives:
As per suggestion I set the Message's width manually and it resolved the problem. What is confusing me is that I thought it would already be set using the line:
desc.place(x=0, y=0, height=0, width=300), but apparently not. At least not so far as to override the aspect ratio.
Tl;dr: Adding desc.configure(width=300) at the end fixes the problem.

"TclError: image", while adding a image to a Label

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.

Python/Tkinter Image and Text label collision

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

How do I use PIL with Tkinter?

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.

Categories