Draw line on image in tkinter - python

I'm trying to make a script that will draw lines on an image in a python GUI. I've been able to get the image on the GUI, but do not know how to draw the additional lines. The script should be able to loop so I can draw more lines.
What I have so far:
import tkinter as Tk
root = Tk.Tk()
background_image=Tk.PhotoImage(file="map.png")
background_label = Tk.Label(root, image=background_image)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
root.wm_geometry("794x370")
root.title('Map')
root.mainloop()

You can do that by first placing your image on a canvas:
import tkinter as Tk
root = Tk.Tk()
canvas = Tk.Canvas(root)
background_image=Tk.PhotoImage(file="map.png")
canvas.pack(fill=Tk.BOTH, expand=1) # Stretch canvas to root window size.
image = canvas.create_image(0, 0, anchor=Tk.NW, image=background_image)
line = canvas.create_line(10, 10, 100, 35, fill="red")
root.wm_geometry("794x370")
root.title('Map')
root.mainloop()

Related

How can I hide the image in Tkinter Python

I want to hide the image in Tkinter Python module. How can I do it?
For example:
from tkinter import *
root = Tk()
root.title("Example")
root.geometry("500x500")
root.resizable(0, 0)
def hide():
# How can I hide the image?
canvas = Canvas(root, width=500, height=500)
canvas.pack()
image = PhotoImage(file='example.png')
img = canvas.create_image(0, 0, anchor=NW, image=image)
hide = Button(root, text="Hide", command=hide)
hide = canvas.create_window(0, 30, anchor=NW, window=hide)
root.mainloop()
I try the [image].destory(), but it's not working.
If you want to remove a canvas object from a canvas, you can use the delete method of the canvas. It takes as a parameter the id of the object to be deleted:
canvas.delete(img)

One of my canvases doesn't show in the Tkinter window (Python)

I'm trying to make a Tkinter window with two canvases: one for inputs, one for results.
The reason for that is that I couldn't find a way to clear just the results when the next input comes in so if there's a way to do that, that would also solve my problem, but I didn't find a way to solve that.
The issue is that the second canvas won't show up on the window. I've tried putting something on it right away, but it still didn't work. Also when searching for a solution, I found a code that I tried for myself and then it worked.
Here's the code:
root = tk.Tk() #I used import tkinter as tk
canvas = tk.Canvas(root, width = 400, height = 200)
canvas.pack(side='top', anchor='nw', fill='x')
canvas2 = tk.Canvas(root, width = 400, height = 600)
canvas.pack(side='top', anchor='nw', fill='both')
You typed canvas.pack(side='top', anchor='nw', fill='both') instead of canvas2.pack(side='top', anchor='nw', fill='both'). Here is the corrected code:
import tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=200, bg="red")
canvas.pack(side='top', anchor='nw', fill='x')
canvas2 = tk.Canvas(root, width=400, height=600, bg="blue")
canvas2.pack(side='top', anchor='nw', fill='both')
root.mainloop()

Center an image when resizing

Working with Tkinter, I need to center entities. When trying to center labels, it will only center it within the first row, and not the window.
I want it centered within the entire window. i.e. the middle. So far, it is only the middle of the top. is this possible?
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image
root = Tk()
# New window, but text appears in the center of the center (the absolute center).
def whatsup():
popup = Tk()
popup.title("Cadillac")
frame = Frame(popup)
frame.pack()
label = ttk.Label(frame, text="Wanna ride in my Cadillac?")
label.pack()
root.title("I Love You")
# 1, 1
button = Button(root, text="Ayo girl", command=whatsup)
button.pack(side=LEFT)
# 1, 2, but to be 2, 2 soon after addition of new items.
canvas = Canvas(root, height=250, width=200)
imageOfCatherine=ImageTk.PhotoImage(Image.open('ccr_on_moon.jpg'))
canvas.create_image(-160, -100, anchor=NW, image=imageOfCatherine)
canvas.pack()
root.mainloop()
You can use grid instead of pack, with rowconfigure and columnconfigure methods like this :
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image
root = Tk()
root.title("I Love You")
# New window, but text appears in the center of the center (the absolute center).
def whatsup():
popup = Tk()
popup.title("Cadillac")
frame = Frame(popup)
frame.pack()
label = ttk.Label(frame, text="Wanna ride in my Cadillac?")
label.pack()
# 1, 1
button = Button(root, text="Ayo girl", command=whatsup)
button.grid(row=0, column=0, sticky='w')
# 1, 2, but to be 2, 2 soon after addition of new items.
canvas = Canvas(root, height=250, width=200)
imageOfCatherine=ImageTk.PhotoImage(Image.open('ccr_on_moon.jpg'))
canvas.create_image(-160, -100, anchor=NW, image=imageOfCatherine)
canvas.grid(row=1, column=1)
root.rowconfigure([0,1,2], weight=1)
root.columnconfigure([0,1,2], weight=1)
root.mainloop()
Answer to comment
This also works, but it's not centered the same way :
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image
root = Tk()
root.title("I Love You")
# New window, but text appears in the center of the center (the absolute center).
def whatsup():
popup = Tk()
popup.title("Cadillac")
frame = Frame(popup)
frame.pack()
label = ttk.Label(frame, text="Wanna ride in my Cadillac?")
label.pack()
# 1, 1
button = Button(root, text="Ayo girl", command=whatsup)
button.grid(row=0, column=0, sticky='w')
# 1, 2, but to be 2, 2 soon after addition of new items.
canvas = Canvas(root, height=250, width=200)
imageOfCatherine=ImageTk.PhotoImage(Image.open('ccr_on_moon.jpg'))
canvas.create_image(-160, -100, anchor=NW, image=imageOfCatherine)
canvas.grid(row=0, column=1, sticky='')
root.rowconfigure(0, weight=1)
root.columnconfigure([0,1], weight=1)
root.mainloop()
After some tinkering (no pun intended), I added expand=YES to frame.pack() in the whatsup() function.
def whatsup():
popup = Tk()
popup.title("Cadillac")
frame = Frame(popup)
frame.pack(expand=YES) # This was the changed line!
label = ttk.Label(frame, text="Wanna ride in my Cadillac?")
label.pack()
This allows for the popup text to become centered.

How to create a tkinter background image?

I need to draw a ball moving on a canvas with a background (floor map) image.
I succeded to load the image, and to draw the ball moving, but the canvas ball is not placed on top of the background.
import Tkinter as tk
import random
import time
from PIL import ImageTk, Image
root = tk.Tk()
root.resizable(width=False, height=False)
root.wm_attributes("-topmost", 1)
path = 'C:\xx\Pictures\xxx.jpg'
img = Image.open(path)
photo = ImageTk.PhotoImage(img)
class Ball:
def __init__(self, canvas, color):
self.canvas = canvas
self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
self.canvas.move(self.id, 245, 100)
def draw(self):
self.canvas.move(self.id, 1, 1)
self.canvas.after(50, self.draw)
canvas = tk.Canvas(root, bd=0, highlightthickness=0)
canvas.pack()
background_label = tk.Label(root, image = photo)
background_label.place(x=0, y=0, relwidth=1.0, relheight=1.0, anchor="center")
background_label.pack( )
ball = Ball(canvas, "red")
ball.draw() #Changed per Bryan Oakley's comment.
root.mainloop()
You load the image in a label that's placed below the canvas you draw the ball in. You have to load the image in the same canvas.
Replace this
background_label = tk.Label(root, image = photo)
background_label.place(x=0, y=0, relwidth=1.0, relheight=1.0, anchor="center")
background_label.pack( )
with this:
canvas.create_image(0, 0, image=photo)
Make sure to create the image before you create the ball to get the z-ordering right.

Placing tkinter widgets in foreground

I cannot achieve to create a Textbox (using tkinter's Text widget) which is in the background and having a Canvas item (e.g. an oval) over it (foregroud) :
import Tkinter as Tk
root = Tk.Tk()
c = Tk.Canvas(root, width=400, height=400, bg='white')
o = c.create_oval(10, 10, 390, 390, fill='red')
c.grid(row=0, column=0, columnspan=2, padx=5, pady=5)
t = Tk.Text(c)
t.place(x=10,y=10)
c.tag_lower(t)
c.tag_raise(o)
root.mainloop()
Even if I use c.tag_lower(t), c.tag_raise(o), it doesn't work. Do you know how to solve this problem ?
This is documented behavior. You cannot draw over other widgets that are embedded in a canvas. There is no workaround. To be able to draw on top of text, your only option is to draw the text using create_text.

Categories