Python Forum
[Tkinter] Why is it so difficult to just ouput an image where I want?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Why is it so difficult to just ouput an image where I want?
#1
from Tkinter import *

root = Tk()
# Remove titlebar    
root.overrideredirect(1)
canvas = Canvas(root, width =100,height=153)
logo=PhotoImage(file="a.png")
canvas.create_image(100, 100, image=logo) 
root.mainloop()
All I get is a blank window of the wrong size in the wrong position.

My requirements:
Simplicity - just output a simple png file (I'll pass it as a parameter if I can get this to work.
No external programs.
No clicking on it
Ability to position it
Ability to destroy it
It will actually be a function called over and over to output selected png files at a specific location.
python2 or 3 - don't care. I ran this in python2

I know the file exists because when it doesn't, I get:
_tkinter.TclError: couldn't open "a.png": no such file or directory

I thought it would be easy to do this in python because the big program I got for my application is in python and I just want to make a few modes (like outputting images).
Reply
#2
Tkinter, on a Mac, and maybe Windows, has problems with a png image. PIL/Pillow claims to support some specific types of PNG https://pillow.readthedocs.io/en/5.1.x/h...s.html#png The simplest thing to do is convert to JPG or some other recognized format using ImageMagick or the Python wrapper = Pythonmagick.
Quote:It will actually be a function called over and over to output selected png files at a specific location
Read the text with the green background at http://effbot.org/tkinterbook/photoimage.htm In your case, you might want to read all of the files into a list, which would keep a reference to them as long as the empty list is not also created in a function (=same problem).
Reply
#3
I converted it to a jpg using gimp and got an error so I tried anothe jpg file that I have been using for a while. Here's what I got:

Error:
Traceback (most recent call last): File "another_picture.py", line 7, in <module> logo=PhotoImage(file="9636a.jpg") File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 3374, in __init__ Image.__init__(self, 'photo', name, cnf, master, **kw) File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 3328, in __init__ self.tk.call(('image', 'create', imgtype, name,) + options) _tkinter.TclError: couldn't recognize data in image file "9636a.jpg"
Reply
#4
This page referenced above, opens a jpeg and places it on a Label. Your code would be similar to place it on a Canvas https://effbot.org/tkinterbook/photoimage.htm
Reply
#5
(Apr-04-2019, 03:34 AM)woooee Wrote: This page referenced above, opens a jpeg and places it on a Label. Your code would be similar to place it on a Canvas https://effbot.org/tkinterbook/photoimage.htm

So here is the updated version. File exists as if I delete it, the program gives me a traceback showing it's missing. Like this, no errors but a blank canvas.
from Tkinter import *
from PIL import Image, ImageTk

root = Tk()
# Remove titlebar    
root.overrideredirect(1)
canvas = Canvas(root, width =100,height=153)
image = Image.open("pngs/a.jpg")
logo = ImageTk.PhotoImage(image)
#logo=PhotoImage(file="pngs/a.jpg)
canvas.create_image(200, 200, image=logo) #Change 0, 0 to whichever coordinates you need
root.mainloop()
If I only had the smarts to learn this stuff any more. Back in the days of wooden ships and iron men, all we had was FORTRAN.
Reply
#6
Hi jpezz

You have to bind the tk-image to an object. In your case for instance to the object root. The canvas needs a layout membership for which i choosed pack. For the canvas.create_image add for instance the option anchor='nw'. So the x/y-coordinates relate to the upper left corner of the image. In your case the image would be place outsite of the visuable surface of the canvas:

from Tkinter import *
from PIL import Image, ImageTk
 
root = Tk()
# Remove titlebar    
#root.overrideredirect(1)
canvas = Canvas(root, width =200,height=200)
canvas.pack()
image = Image.open("pngs/a.jpg")
#logo=PhotoImage(file="pngs/a.jpg)
root.logo = ImageTk.PhotoImage(image)

canvas.create_image(10, 10, image=root.logo, anchor='nw')

root.mainloop()
wuf :-)
Reply
#7
(Apr-05-2019, 01:19 PM)wuf Wrote: Hi jpezz

You have to bind the tk-image to an object. In your case for instance to the object root. The canvas needs a layout membership for which i choosed pack. For the canvas.create_image add for instance the option anchor='nw'. So the x/y-coordinates relate to the upper left corner of the image. In your case the image would be place outsite of the visuable surface of the canvas:

from Tkinter import *
from PIL import Image, ImageTk
 
root = Tk()
# Remove titlebar    
#root.overrideredirect(1)
canvas = Canvas(root, width =200,height=200)
canvas.pack()
image = Image.open("pngs/a.jpg")
#logo=PhotoImage(file="pngs/a.jpg)
root.logo = ImageTk.PhotoImage(image)

canvas.create_image(10, 10, image=root.logo, anchor='nw')

root.mainloop()
wuf :-)

I got it! I misunderstood the coordinates in the canvas.create_image statement. I thought it was the POSITION of the canvas in the window. Instead I was locating the image outside the canvas. However, I would like to position the canvas in a specific location. I found nothing on that but did find something on Label so I tried this:
canvas.place(x=50,y=100)
but it doesn't work. How can I position the canvas itself on the screen?
Reply
#8
Hi jpezz

You can't place a Canvas directly on the screen. It must be embedded on the main window. Here some different placements of an image in a tk-Application:

# -*- coding: utf-8 -*

try:
    # Import Tkinter for Python 2.xx
    import Tkinter as tk
except ImportError:
    # Or import Tkinter for Python 3.xx
    import tkinter as tk
    
from PIL import Image, ImageTk

MAIN_WIN_TITLE = "Image Placements"
MAIN_WIN_XPOS = 100
MAIN_WIN_YPOS = 100
MAIN_WIN_WIDTH = 800
MAIN_WIN_HEIGHT = 600

CANVAS_XPOS = 50
CANVAS_YPOS = 50
CANVAS_WIDTH = 400
CANVAS_HEIGHT = 400
CANVAS_BG = 'steelblue'
 
root = tk.Tk()
root.title(MAIN_WIN_TITLE)

# Placement of the main window
root.geometry("{}x{}+{}+{}".format(
    MAIN_WIN_WIDTH, MAIN_WIN_HEIGHT, MAIN_WIN_XPOS, MAIN_WIN_YPOS))

# Get the .jpg image and convert it to tkinter format
image = Image.open("pngs/a.jpg")
root.test_image = ImageTk.PhotoImage(image)

# Placement of a canvas on the main window 
canvas = tk.Canvas(root, bg=CANVAS_BG)
canvas.place(x=CANVAS_XPOS, y=CANVAS_YPOS, width=CANVAS_WIDTH,
    height=CANVAS_HEIGHT)
    
# Place the image as canvas image object directly on the canvas by
# useage of coordinates
canvas.create_image(15, 25, image=root.test_image, anchor='nw')

# Create a label widget containing the image and place it in a canvas
# window object on the canvas
image_label = tk.Label(canvas, text="Image Label placed\non canvas",
    compound='bottom', image=root.test_image)
canvas.create_window(200, 200, anchor='nw', window=image_label)

# Create a label widget containig the image and place it directly on
# the main window
image_label = tk.Label(root, text="Image Label placed\non main window",
    compound='bottom', image=root.test_image)
image_label.place(x=500, y=50)

root.mainloop()
wuf :-)
Reply
#9
(Apr-05-2019, 04:26 PM)wuf Wrote: Hi jpezz

You can't place a Canvas directly on the screen. It must be embedded on the main window. Here some different placements of an image in a tk-Application:

[/python]wuf :-)
Great! Wonderful explanation of the choices and I can easily change the numbers so that canvas and move to different positions Since I have used the label widget before (but don't yet fully understand it), I'd prefer not to have to have a canvas. I played around with your program and I see how I can move things around.
My objective would be to put out a single letter in the Label but it would be big enough for multiple letters. Then I would, in a function, update the label to add an additional letter. I tried just simply creating the label then updating it in the mainloop so this:
# Create a label widget containig the image and place it directly on
# the main window
image_label = tk.Label(root, text="Image Label placed\non main window",
    compound='bottom', image=root.test_image)
image_label.place(x=500, y=50)
looks like this now:
# Create a label widget containig the image and place it directly on
# the main window
image_label = tk.Label(root, text="Image Label placed\non main window",
    compound='bottom', image=root.test_image)
image_label.place(x=500, y=50)

image2 = Image.open("pngs/b.png")
root.test_image = ImageTk.PhotoImage(image2)
image_label.place(x=600, y=50)
image_label.config (root,image=root.test_image)
and I get this error.
Quote:Traceback (most recent call last):
File "his_original.py", line 58, in <module>
root.place(x=600, y=50)
File "/usr/lib/python3.6/tkinter/__init__.py", line 2101, in __getattr__
return getattr(self.tk, attr)
AttributeError: '_tkinter.tkapp' object has no attribute 'place'

Fumbling my way through python one error at a time.
Reply
#10
Hi jpezz

Make following alteration:
image2 = Image.open("pngs/b.png")
root.test_image2 = ImageTk.PhotoImage(image2)
image_label.place(x=600, y=50)
image_label.config(image=root.test_image2)
wuf :-)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Switching from tkinter to gtk is difficult! snakes 1 1,422 Aug-08-2022, 10:35 PM
Last Post: woooee

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020