python tkinter canvas when rectangle clicked - python

I've been trying to make a function run when I click a rectangle on a tk canvas.
Here is the code:
from tkinter import *
window = Tk()
c = Canvas(window, width=300, height=300)
def clear():
canvas.delete(ALL)
playbutton = c.create_rectangle(75, 25, 225, 75, fill="red")
playtext = c.create_text(150, 50, text="Play", font=("Papyrus", 26), fill='blue')
c.pack()
window.mainloop()
does anyone know what I should do?

You can add tags on the items you want to bind events to.
The event you want here is <Button-1>, which is left mousebutton.
To apply this to your example, you can do like this:
from tkinter import Tk, Canvas
window = Tk()
c = Canvas(window, width=300, height=300)
def clear():
canvas.delete(ALL)
def clicked(*args):
print("You clicked play!")
playbutton = c.create_rectangle(75, 25, 225, 75, fill="red",tags="playbutton")
playtext = c.create_text(150, 50, text="Play", font=("Papyrus", 26), fill='blue',tags="playbutton")
c.tag_bind("playbutton","<Button-1>",clicked)
c.pack()
window.mainloop()

Related

Problems while drawing straight line and dragging in Tkinter canvas

So, I'm trying to draw vertical lines in canvas on the click of the button "line".
These are the problems and my requirements:
When i try click on the line drawn to drag it to a position, it repels away from the mouse cursor but moves in the correct direction. What do i do to prevent this?
On subsequent clicks on the "line" button, i want a new line to be drawn (every time i click) while the original lines stays in the canvas unmoved.
The latest line is the only one which can be dragged. All other lines should be static.
I want coordinates of all these drawn lines. How do i get these?
This is the code i've written:
from tkinter import *
import tkinter
root = Tk()
canvas = tkinter.Canvas(root, width = 480,height = 600)
canvas.pack()
def draw_lines():
canvas.create_line(300, 35, 300, 200, dash=(4, 2))
def drag(event):
event.widget.place(x=event.x_root, y=event.y_root,anchor=CENTER)
canvas.bind("<B1-Motion>", drag)
btn1 = Button(root, text = 'line', bd = '5',command = draw_lines)
btn2 = Button(root, text = 'Close', bd = '5',command = root.destroy)
btn1.pack(side = 'top')
btn2.pack(side = 'top')
canvas.mainloop()
please help!!!!
Using Python 3.11.0rc1.
I added:
geometry. so it will not resize when dragging.
Canvas. You have to play around with height set to 800
I removed bd=5. You can suit yourself. Don't use quote.
I removed Quotes for this btn1.pack(side=TOP)
At last canvas.pack() always next to mainloop()
Here is the code re-worked:
from tkinter import *
root = Tk()
root.geometry('400x650')
canvas = Canvas(root, width=480, height=600)
def draw_lines():
canvas.create_line(300, 35, 300, 200, dash=(4, 2))
def drag(event):
event.widget.place(x=event.x_root, y=event.y_root,anchor=CENTER)
canvas.bind("<B1-Motion>", drag)
btn1 = Button(root, text='line', command=draw_lines)
btn2 = Button(root, text= 'Close', command=root.destroy)
btn1.pack(side=TOP)
btn2.pack(side=TOP)
canvas.pack()
canvas.mainloop()
Result output:

How to call Turtle window from a GUI

I'm trying to open a Turtle window from a GUI to select a position on the image with a mouse click. The x and y coordinates are then returned as an input to the GUI.
Here is a minimal working example:
from tkinter import *
from tkinter import font as tkFont
import turtle
xclick = 0
yclick = 0
def callback3():
getcoordinates()
def getcoordinates():
screen = turtle.Screen()
screen.setup(400, 400)
screen.bgpic("stunden.gif")
screen.onscreenclick(modifyglobalvariables)
def modifyglobalvariables(rawx,rawy):
global xclick
global yclick
xclick = int(rawx//1)
yclick = int(rawy//1)
print(xclick)
print(yclick)
turtle.bye()
root = Tk()
helv30 = tkFont.Font(family='Helvetica', size=30)
button1 = Button(root, text = "1", width=3, font=helv30, borderwidth=0, command=callback3)
button1.grid(row=0, column=0, padx=5, pady=0)
root.mainloop()
Then the error image "pyimage2" doesn't exist shows up. I found out, that it has something to do with two instances of Tk, as there is the root and the turtle window and that I should solve it with Toplevel(). However, after hours of research and try and error I still could not come up with the right solution to make my code work. Any help is greatly appreciated.
Here's how to implement it directly in tkinter — so no turtle module required — as I suggested earlier in a (now-deleted) comment:
from tkinter import *
from tkinter import font as tkFont
CLOCK_IMAGE_PATH = 'clock.png'
xclick, yclick = 0, 0
def callback3():
window = Toplevel()
window.title("Stunden")
img = PhotoImage(file=CLOCK_IMAGE_PATH)
img_width, img_height = img.width(), img.height()
window.minsize(width=img_width, height=img_height)
canvas = Canvas(window, width=img_width, height=img_height)
canvas.pack()
canvas.image = img # Keep reference to avoid image being garbage collected.
canvas.create_image(0, 0, anchor='nw', image=img)
canvas.bind("<Button-1>", get_coordinates) # Set up event-handler callback.
def get_coordinates(event):
global xclick, yclick
xclick = int(event.x // 1)
yclick = int(event.y // 1)
print(f'xclick={xclick}, yclick={yclick}')
root = Tk()
helv30 = tkFont.Font(family='Helvetica', size=30)
button1 = Button(root, text="1", width=3, font=helv30, borderwidth=0, command=callback3)
button1.grid(row=0, column=0, padx=5, pady=0)
root.mainloop()

My entry in tkinter is behind my canvas, how can i change it?

Im always on my project on tkinter and i have created a border function to create a rectangle with a specificate border, anyway my problem its my entry is behind my rectangle how can i change it ??
its is my code:
def SetBorder(event):
Border(window, 120, 21, 20, bg_color_hex, border_color_hex, 3)
def NewProject():
global window
window = tk.Toplevel(frame)
window.title("New Project")
window.geometry("720x480")
window.resizable(0, 0)
window.config(bg=bg_color_hex)
Project_Name_Label = Label(window, text="Project Name:")
Project_Name_Label.place(x=15, y=20)
Project_Name_Label.config(fg=text_color_hex, bg=bg_color_hex)
global Project_Name_Entry
Project_Name_Entry = Entry(window, width=20)
Project_Name_Entry.config(bg=entry_color, bd=0, fg=text_color_hex)
Project_Name_Entry.bind("<Button-1>", SetBorder)
Project_Name_Entry.place(x=120, y=21)

tkinter window glitching out after a while (tkinter)

tkinter gui glitching out
anyone know why my tkinter is glitching out like this after around 2.5 minutes?
this code is the minimum example so it wont have the coloured cells but it is the same problem
from tkinter import *
import random
tk = Tk()
tk.wm_title("Battleship")
# forming tkinter window
def baseGrid():
tk.player_canvas = Canvas(tk, height=300, width=300, highlightbackground='black', highlightthickness=0.5)
tk.ai_canvas = Canvas(tk, height=300, width=300, highlightbackground='black', highlightthickness=0.5)
tk.player_canvas.grid(row=1, column=0, padx=50)
tk.ai_canvas.grid(row=1, column=1, padx=50)
for x in range(10):
for y in range(10):
tk.player_canvas.create_rectangle(x * 30, y * 30, 300, 300, fill='white')
tk.ai_canvas.create_rectangle(x * 30, y * 30, 300, 300, fill='white')
while True:
tk.update()
tk.update_idletasks()
place = baseGrid()
Your loop was causing a memory leak. I'm not sure exactly because I didn't test what was causing it, but I'm almost positive it was because you were drawing an infinite amount of rectangles on top of each other. I simply just changed your code to how I would write it to fix it.
from tkinter import *
import random
tk = Tk()
tk.wm_title("Battleship")
# forming tkinter window
# While technically you can add the canvas objects to your window I don't know if that is best practice.
player_canvas = Canvas(tk, height=300, width=300, highlightbackground='black', highlightthickness=0.5)
ai_canvas = Canvas(tk, height=300, width=300, highlightbackground='black', highlightthickness=0.5)
def baseGrid():
player_canvas.grid(row=1, column=0, padx=50)
ai_canvas.grid(row=1, column=1, padx=50)
for x in range(10):
for y in range(10):
player_canvas.create_rectangle(x * 30, y * 30, 300, 300, fill='white')
ai_canvas.create_rectangle(x * 30, y * 30, 300, 300, fill='white')
baseGrid() # you are not returning anything so you do not need the place variable
tk.mainloop() # you should just run mainloop so that Tkinter can manage the loop.

How to activate tkinter buttons with keyboard?

Im making a musical app, an application for playing drums with GUI(graphical user interface). So i already have the buttons labeled for every piece of the drums and i have my drum kit already drawn in my canvas, but i dont know how to activate the buttons with my computer keyboard, is it possible?
Thanks for the support
Have a happy day
Here is the code:
##import libraries
from Tkinter import *
from winsound import *
import os
import ttk
##Initialize
root = Tk()
root.geometry('{}x{}'.format(938, 600))
canvas = Canvas(root, width = 938, height = 505, bg = 'white')
canvas.pack()
label = ttk.Label(root, text ="Hello my name is Scorp welcome to this drums
app")
label.pack()
label.config(foreground ='black')
label.config(font = ('arial',15, 'bold'))
##PhotoImage(file ="g1.gif")
logo =PhotoImage(file ="drums1.gif")
imageFinal = canvas.create_image(480, 260, image = logo)
##logo =PhotoImage(file ="drums.gif")
##imageFinal = canvas.create_image(530, 80, image = logo)
def move():
canvas.move(imageFinal, 10, 10 )
canvas.move(label, 10, 10)
canvas.update()
def play1():
os.system('hi_hat.wav')
##define buttons
button = Button(text = 'move', height = 2, width = 4, command = move)
button.place(x=556, y=550)
button1 = Button(text = 'Hi-Hat', height = 2, width = 10, command = play1)
button1.place(x=20, y=240)
root.mainloop()
WRITTEN IN PYTHON BY ALAN ABUNDIS
You can bind your keyboard keys with your GUI button functions so whenever you you press the selected keyboard key the function will access.
First you have to create your button:
btn = Button(text = 'move', height = 2, width = 4, command = move)
button.place(x=556, y=550)
Now to bind it with a key(for example shift+z):
btn.bind("<Shift-Z>", move)
And now to define function:
def move(event=' '):
canvas.move(imageFinal, 10, 10 )
canvas.move(label, 10, 10)
canvas.update()
You have to give a 'event' argument to your function which you are binding with a key. I have set the default value of event to a empty string so whenever you press the button on screen using mouse it wont give you an error.

Categories