Tkinter smooth transition between frames - python

# Import the required libraries
from tkinter import *
from PIL import Image, ImageTk
# Create an instance of tkinter frame
win = Tk()
# Set the size of the tkinter window
win.geometry("700x350")
# Define a Canvas widget
canvas = Canvas(win, width=600, height=400, bg="white")
canvas.pack(pady=20)
# Add Images to Canvas widget
x = 250
y = 120
image = ImageTk.PhotoImage(Image.open('map.png'))
img = canvas.create_image(x, y, anchor=NW, image=image)
def left(e):
global x, y
x -= 0.9
canvas.coords(img, x, y)
def right(e):
global x, y
x += 0.9
canvas.coords(img, x, y)
def up(e):
global x, y
y -= 0.9
canvas.coords(img, x, y)
def down(e):
global x, y
y += 0.9
canvas.coords(img, x, y)
# Bind the move function
win.bind("<Left>", left)
win.bind("<Right>", right)
win.bind("<Up>", up)
win.bind("<Down>", down)
win.mainloop()
map.png is https://www.dropbox.com/s/wfq4skai66nexxr/map.png?dl=0. If you press left or right arrow keys, you will see the black words look slightly lagging. Is there a way to fix that without changing the 0.9?

Related

Why doesn't this image move when the key is pressed?

Python and Tkinter nebwie. I tried making an image in tkinter and have it move using the arrows. The image shows just it should, but when I try to move it using the arrows, it doesn't work at all. Any idea why? I use python 2.7.18 and I'm on the latest version of Ubuntu
from Tkinter import *
############
#things
w = 500
h = 500
width=w
height=h
#############
######################################################################
#window
window = Tk()
window.title("Moving image")
canvas = Canvas(window, width = 500, height = 500)
canvas.pack()
my_image = PhotoImage(file="/home/user/Documents/ddd.png")
canvas.create_image(260, 125, anchor = NW, image=my_image)
#######################################################################
################################
#var
def up(event):
x = 0
y = -10
canvas.move(my_image, x, y)
def down(event):
x = 0
y = 10
canvas.move(my_image, x, y)
def left(event):
x = -10
y = 0
canvas.move(my_image, x, y)
def right(event):
x = 10
y = 0
canvas.move(my_image, x, y)
###############################
###############################
#binds
window.bind("<Up>", up)
window.bind("<Down>", down)
window.bind("<Left>", left)
window.bind("<Right>", right)
window.mainloop()
##############################
You are trying to move the wrong object. Use the object, which is returned by canvas.create_image:
image_id = canvas.create_image(260, 125, anchor = NW, image=my_image)
...
canvas.move(image_id, x, y)
Alternatively, you can attach a tag to the image:
canvas.create_image(260, 125, anchor=NW, image=my_image, tag="move")
...
canvas.move("move", x, y)
This will move all objects, which have this specific tag attached.

How to draw an image, so that my image is used as a brush

I created this little algorithm that is supposed to draw an image (imagine that my brush is an image) so that when I keep clicking I will draw the image, but as you can see if you test the code, it does not paint.
What it does is just moves the image across the Canvas.
Is there a way for the image to remain on the Canvas?
Here is my code:
from tkinter import *
from PIL import Image, ImageTk
master = Tk()
w = Canvas(master, width=800, height=400)
w.pack(expand = YES, fill = BOTH)
imagen = Image.open('C:/Users/Andres/Desktop/hola.png')
P_img = ImageTk.PhotoImage(imagen)
def paint( event ):
global w, P_img_crop
#I get the mouse coordinates
x, y = ( event.x - 1 ), ( event.y - 1 )
#I open and draw the image
img_crop = Image.open('C:/Users/Andres/Desktop/papa.png')
P_img_crop = ImageTk.PhotoImage(img_crop)
w.create_image((x,y), anchor=NW, image=P_img_crop)
w.bind( "<B1-Motion>", paint )
mainloop()
I GOT IT
I did not know that the image that was drawn on the canvas, should be saved, so what I did is store the images in a matrix, which belongs to the canvas.
Here is the code, just in case ...
from tkinter import *
from PIL import Image, ImageTk
master = Tk()
w = Canvas(master, width=800, height=400)
w.dib = [{} for k in range(10000)]
w.pack(expand = YES, fill = BOTH)
puntero = 0
def paint( event ):
global w, P_img_crop, puntero
#I get the mouse coordinates
x, y = ( event.x - 1 ), ( event.y - 1 )
#I open and draw the image
img_crop = Image.open('C:/Users/Andres/Documents/PROYECTOS INCONCLUSOS/PAINT MATEW PYTHON/hola.png')
w.dib[puntero]['image'] = ImageTk.PhotoImage(img_crop)
w.create_image((x,y), anchor=NW, image=w.dib[puntero]['image'])
puntero += 1
if(puntero >=10000):
puntero = 0
w.bind( "<B1-Motion>", paint )
mainloop()
All you need to do remove the image creation inside the paint() function. Then you will achieve what you want because otherwise it creates the image again and doesn't save a copy behind. In other words, when you move the brush, the previous image is garbage collected.
Code:
from tkinter import *
from PIL import Image, ImageTk
master = Tk()
w = Canvas(master, width=800, height=400)
w.pack(expand = YES, fill = BOTH)
img_crop = Image.open('yes.png')
P_img_crop = ImageTk.PhotoImage(img_crop)
def paint(event):
global P_img_crop
#I get the mouse coordinates
x, y = event.x - 1, event.y - 1
#I open and draw the image
w.create_image(x, y, image = P_img_crop)
w.bind("<B1-Motion>", paint)
master.mainloop()
Hope this helps!

How to change window geometry in tkinter using after?

What I want to achieve is displaying an image on another application window with regard to its coordinates. For example, it should appear 100 pixels down and 100 pixels left to the left upper corner. I am using transparent window for the image, and it displays an image properly but it doesn't update its coordinates.
Here is my code:
import tkinter as tk # Python 3
from functions import window_coordinates # it takes x, y, width, heigth of the window
x, y, w, h = window_coordinates("window_name")
def update_coordinates():
global x, y, w, h
x, y, w, h = window_coordinates("window_name")
root.geometry("+{}+{}".format(x + 100, y + 100))
print("update_coordinates function")
root = tk.Tk()
# The image must be stored to Tk or it will be garbage collected.
root.image = tk.PhotoImage(file='path/to/image.png')
label = tk.Label(root, image=root.image, bg='white')
root.overrideredirect(True)
root.geometry("+{}+{}".format(x+100, y+100))
root.lift()
root.wm_attributes("-topmost", True)
root.wm_attributes("-disabled", True)
root.wm_attributes("-transparentcolor", "white")
label.pack()
label.after(100, update_coordinates)
label.mainloop()
Thanks for help.
EDIT1: I put root.geometry("+{}+{}".format(x + 100, y + 100)) inside the function but it didn't help. Also I added print statement to see how this function works and it's called only once at the beginning.
OK, I found the answer. There was a mistake in the function. Callback didn't work. Right code:
import tkinter as tk # Python 3
from functions import window_coordinates
x, y, w, h = window_coordinates("3949206036")
def update_coordinates():
global x, y, w, h
x, y, w, h = window_coordinates("3949206036")
root.geometry("+{}+{}".format(x + 100, y + 100))
label.after(1, update_coordinates) # This addition was needed
root = tk.Tk()
# The image must be stored to Tk or it will be garbage collected.
root.image = tk.PhotoImage(file='d:/Python/Projects/Data-mining/samples/avatar.png')
label = tk.Label(root, image=root.image, bg='white')
root.overrideredirect(True)
root.geometry("+{}+{}".format(x+100, y+100))
root.lift()
root.wm_attributes("-topmost", True)
root.wm_attributes("-disabled", True)
root.wm_attributes("-transparentcolor", "white")
label.pack()
label.after(1, update_coordinates)
label.mainloop()

drag an arc after creating a line tkinter

Here was the code to draw a line. Is it possible to let the user drag a line so that it forms a curve?
from tkinter import Canvas, Tk
# Image dimensions
w,h = 640,480
# Create canvas
root = Tk()
canvas = Canvas(root, width = w, height = h, bg = 'white')
canvas.pack()
def on_click(event):
""" set starting point of the line """
global x1, y1
x1 = event.x
y1 = event.y
def on_click_release(event):
""" draw the line """
canvas.create_line(x1, y1, event.x, event.y)
def clear_canvas(event):
canvas.delete('all')
canvas.bind("<Button-1>", on_click)
canvas.bind("<ButtonRelease-1>", on_click_release)
root.bind("<Key-c>", clear_canvas)
root.mainloop()
Once again thank youuuuu!!! :)))))
For an arc you need to track the mouse as it moves across the screen, rather than just the start and end points.
The code below will only create arcs from the bottom left, to the bottom right of a rectangle, but you can add any other arcs you want by changing the start angle and the extent angle of the arc.
from tkinter import Canvas, Tk, ARC
# Image dimensions
w,h = 640,480
# Create canvas
root = Tk()
canvas = Canvas(root, width = w, height = h, bg = 'white')
canvas.pack()
# curve points
global points
global temp_arc
points = []
temp_arc = None
def arc():
x = [point[0] for point in points]
y = [point[1] for point in points]
return canvas.create_arc(x[0], y[0], x[-1], y[-1], start = 0, style = ARC, width = 2, extent = 180)
def motion(event):
global temp_arc
points.append([event.x, event.y])
if temp_arc != None:
canvas.delete(temp_arc)
temp_arc = arc()
def on_click_release(event):
arc()
global points
points = []
def clear_canvas(event):
canvas.delete('all')
canvas.bind("<B1-Motion>", motion)
canvas.bind("<ButtonRelease-1>", on_click_release)
root.bind("<Key-c>", clear_canvas)
root.mainloop()

How to move a Canvas image using Tkinter?

Guys I am working on a code which needs to move an image in python using Tkinter(canvas)
This is creating problems for me. The image is being displayed but it is not moving.
from Tkinter import *
root = Tk()
root.title("Click me!")
def next_image(event):
global toggle_flag
global x, y, photo1
# display photo2, move to right, y stays same
canvas1.create_image(x+10, y, image=photo1)
canvas1.create_image(x+20, y, image=photo1)
canvas1.create_image(x+30, y, image=photo1)
canvas1.create_image(x+40, y, image=photo1)
canvas1.create_image(x+50, y, image=photo1)
canvas1.create_image(x+60, y, image=photo1)
canvas1.create_image(x+70, y, image=photo1)
canvas1.create_image(x+100, y, image=photo1)
image1 = "C:\Python26\Lib\site-packages\pygame\examples\data\ADN_animation.gif" #use some random gif
photo1 = PhotoImage(file=image1)
# make canvas the size of image1/photo1
width1 = photo1.width()
height1 = photo1.height()
canvas1 = Canvas(width=width1, height=height1)
canvas1.pack()
# display photo1, x, y is center (anchor=CENTER is default)
x = (width1)/2.0
y = (height1)/2.0
canvas1.create_image(x, y, image=photo1)
canvas1.bind('<Button-1>', next_image) # bind left mouse click
root.mainloop()
Canvas provides move method. Arguments are item you want to move, relative x offset from the previous position, y offset.
You need to save the return value of the create_image to pass it to the move method.
Also make sure the canvas is expandable (pack(expand=1, fill=BOTH) in the following code)
from Tkinter import *
root = Tk()
def next_image(event):
canvas1.move(item, 10, 0) # <--- Use Canvas.move method.
image1 = r"C:\Python26\Lib\site-packages\pygame\examples\data\ADN_animation.gif"
photo1 = PhotoImage(file=image1)
width1 = photo1.width()
height1 = photo1.height()
canvas1 = Canvas(width=width1, height=height1)
canvas1.pack(expand=1, fill=BOTH) # <--- Make your canvas expandable.
x = (width1)/2.0
y = (height1)/2.0
item = canvas1.create_image(x, y, image=photo1) # <--- Save the return value of the create_* method.
canvas1.bind('<Button-1>', next_image)
root.mainloop()
UPDATE according to the comment
Using after, you can schedule the function to be called after given time.
def next_image(event=None):
canvas1.move(item, 10, 0)
canvas1.after(100, next_image) # Call this function after 100 ms.

Categories

Resources