How to detect click on image? - python

guys, I'm currently making Chess in Python using Tkinter and wanted to know how to detect if an image is clicked?
This code adds a click function to each image I have stored within a dictionary
def MouseClickOnEachPiece(self, rows, columns, event):
global AllPieces
while True:
for ThePieces in AllPieces:
if board[rows][columns] == ThePieces:
self.canvas.bind('<Button-1>', MakeMove)
elif board[rows][columns] != ThePieces:
continue
This code is used to make the move
def MakeMove(self, rows, columns, event):
global AllPieces
print("You have clicked at: ", event.x , event.y)
while True:
for i in AllPieces:
if #the image is clicked : # -- What would i use to check if the image is clicked?
canvas.move(i, #themove )

If possible, you can use a button and place an image on the button instead.
from tkinter import *
from tkinter import ttk
root = Tk()
button = ttk.Button(root)
button.pack()
theImage = PhotoImage(file = "source")
button.config(image = theImage)

Related

Is it possible to have a mouse left click after 2 seconds of inactivity - Tkinter

I am making a GUI in Tkinter, python, which can be navigated using a mouse cursor but no buttons/keys.
I am trying to solve a current problem of having the mouse left click without anyone pressing the physical mouse button or a key on the keyboard. I would like to have the mouse auto click after 2 seconds of inactivity.
For example i hover over a button and wait two seconds then the button is pressed.
I would like to say i have tried everything but i cant find anything to try. I thought about using the .invoke() function with a timing loop but i cant get it to run while my gui is open. ill show my gui code. Maybe i am doing something wrong, but if i place the .invoke function after the win.mainloop then it wont even run untill i close the gui tk window.
win = Tk()
# get the dimensions of the primary screen
app = wx.App(False)
w, h = wx.GetDisplaySize()
geometry = "%dx%d" % (w,h)
win.geometry(geometry)
win.attributes('-fullscreen', True)
win.config(cursor="circle")
# get the grid image
bg = Image.open('grid_image.png')
img = bg.resize((w, h))
grid_img=ImageTk.PhotoImage(img)
image_label = Label(win, image=grid_img)
image_label.place(x=0, y=0, relwidth=1, relheight=1)
# print an image of a green circle
gw = int(w/26)
gh = int(h/15)
g_circle = Image.open('green_circle.png')
g_img = g_circle.resize((gw,gh))
g_circle_image=ImageTk.PhotoImage(g_img)
g_label = Label(win, image=g_circle_image)
g_label.place(x=w/8, y=h/8)
g_btn = Button(win, image=g_circle_image, command=win.destroy)
g_btn.place(x=(w/8), y=(h/8))
# print an image of a blue circle
bw = int(w/26)
bh = int(h/15)
b_circle = Image.open('circle.png')
b_img = b_circle.resize((bw,bh))
b_circle_image=ImageTk.PhotoImage(b_img)
b_label = Label(win, image=b_circle_image)
b_label.place(x=(w/8)*5, y=(h/8)*5)
b_btn = Button(win, image=b_circle_image, command=win.destroy)
b_btn.place(x=(w/8)*5, y=(h/8)*5)
win.mainloop()
Any help with solving this would be much appreciated.
As you already seem to be confirming the option with tk.Button().invoke() you can use tk.Button.bind('<Enter>', _onhover) to detect the mouse over your button and tk.Button.bind('<Leave>', _onleave)
Define two functions like that:
def _onhover(event):
global _current_button
button = event.widget
_current_button = button
button.after(2000, lambda b=button: _invocation(b))
def _onleave(event):
global _current_button
_current_button = None
def _invocation(button):
if _current_button is button:
button.invoke()

How do I enable right click in entry and output widget for pasting and copying respectively in Tkinter?

I'm still working on the translator app, with the help of Python Dictionary. But I have this challenge: I want to be able to right click in the entry widget and paste keys as well as right click in the output widget and copy values. I'm only able to do so with keyboard shortcut; for convenience sake, I want to be able to do so with the mouse. Thanks. Below is the code:
from tkinter import *
import tkinter. messagebox
root=Tk()
root.geometry('250x250')
root.title("Meta' Translator")
root.configure(background="#35424a")
from playsound import playsound
#Entry widget object
textin = StringVar()
#press ENTER key to activate translate button
def returnPressed(event):
clk()
def clk():
entered = ent.get().lower() #get user input and convert to lowercase
output.delete(0.0,END)
if len(entered) > 0:
try:
textin = exlist[entered]
except:
textin = 'Word not found'
output.insert(0.0,textin)
def play():
text = output.get("0.0", "end").strip("\n")
if text == "əsɔ́":
playsound("hoe.mp3")
elif text == "jam":
playsound("axe.mp3")
elif text == "ɨghə́":
playsound("eye.mp3")
else:
# If there is no sound file for the translation:
playsound("eze.mp3")
#heading
lab0=Label(root,text='Translate English Words to Meta\'',bg="#35424a",fg="silver",font=
('none 11 bold'))
lab0.place(x=0,y=2)
#Entry field
ent=Entry(root,width=15,font=('Times 18'),textvar=textin,bg='white')
ent.place(x=30,y=30)
#focus on entry widget
ent.focus()
#Search button
but=Button(root,padx=1,pady=1,text='Translate',command=clk,bg='powder blue',font=('none 18
bold'))
but.place(x=60,y=90)
#press ENTER key to activate Translate button
root.bind('<Return>', returnPressed)
#output field
output=Text(root,width=15,height=1,font=('Times 18'),fg="black")
output.place(x=30,y=170)
#play button
play_button=Button(root,padx=1,pady=1,text='Play',command=play,bg='powder blue',font=('none
10 bold'))
play_button.place(x=100,y=210)
#prevent sizing of window
root.resizable(False,False)
#Dictionary
exlist={
"hat":"ɨ̀də̀m",
"hoe":"əsɔ́",
"honey":"jú",
"chest":"ɨgɔ̂",
"eye":"ɨghə́",
"ear":"ǝ̀tǒŋ",
"axe":"jam"
}
root.mainloop()
Since your code has a lot of dependency, it cannot be run on another system, so here is a common example which you should be able to implement to your code easily:
from tkinter import *
root = Tk()
def popup(event):
try:
menu.tk_popup(event.x_root,event.y_root) # Pop the menu up in the given coordinates
finally:
menu.grab_release() # Release it once an option is selected
def paste():
clipboard = root.clipboard_get() # Get the copied item from system clipboard
e.insert('end',clipboard) # Insert the item into the entry widget
def copy():
inp = e.get() # Get the text inside entry widget
root.clipboard_clear() # Clear the tkinter clipboard
root.clipboard_append(inp) # Append to system clipboard
menu = Menu(root,tearoff=0) # Create a menu
menu.add_command(label='Copy',command=copy) # Create labels and commands
menu.add_command(label='Paste',command=paste)
e = Entry(root) # Create an entry
e.pack(padx=10,pady=10)
e.bind('<Button-3>',popup) # Bind a func to right click
root.mainloop()
I have explained it with comments to understand on-the-go, nothing complicated. The menu just pops up when you right click on the entry as the function is binded to the entry alone. I think, without clipboard_clear() it would append all the items in the tkinter clipboard to the system clipboard.

How to drag text which is printed over Image (in canvas) using mouse in python?

I want to add a Drag Text Feature in canvas to change the position of text using mouse.
from PIL import Image,ImageFont,ImageDraw,ImageTk
import tkinter as tk
root = tk.Tk()
root.title('Demo')
root.geometry('400x50')
def func_image():
img_window = tk.Toplevel()
img_window.grab_set()
photo = Image.open(r'E:\side_300.png')
wi,hi = photo.size
fonty = ImageFont.truetype('arial.ttf',18)
draw = ImageDraw.Draw(photo)
draw.text((50,50),text=text.get(),fill='red',font=fonty)
new_photo = photo
can_photo = ImageTk.PhotoImage(new_photo)
canvas = tk.Canvas(img_window,height=500,width=500)
canvas.pack(anchor='n')
canvas.create_image(wi/2,hi/2,image=can_photo,anchor='center')
img_window.mainloop()
lbl_text = tk.Label(root,text='Enter Text :')
lbl_text.grid(row=0,column=0)
text = tk.Entry()
text.grid(row=0,column=1)
btn = tk.Button(root,text='Click Me',command=func_image)
btn.grid(row=0,column=2)
root.mainloop()
When you run the code it will firstly open a window with name 'Demo' which contains one entry box and a button.
When you click on a Button 'Click Me' after entering some text into entry box it will go to a function func_image and opens a new window which contain a canvas filled with new_image.
Quick Disclaimer: I don't have a lot of experience with PIL, so i don't know how to remove text that has already been drawn. Maybe you can figure that one out yourself. But apart from that, i know some things about tkinter. My idea would be the following:
Bind a function to the <B1-motion> event (Button 1 is being held down and moved) that will constantly get the position of the mouse inside the window and draw new text at that position, while deleting the previous text.
import...
...
def func_image():
img_window = tk.Toplevel()
...
...
draw = ImageDraw.Draw(photo)
draw.text((50,50),text=text.get(),fill='red',font=fonty)
...
def move_text(event):
# here you would delete your previous text
x = event.x
y = event.y
draw.text((x,y),text=text.get(),fill='red',font=fonty
img_window.bind('<B1-Motion>', move_text)
That being said, i think it would be a better idea to use Canvas.create_text (more on effbot.org) in order to write your text on the image. It's really easy to drag around text on a Canvas, here's a little example:
import tkinter as tk
root = tk.Tk()
def change_position(event):
x = event.x
y = event.y
# 20x20 square around mouse to make sure text only gets targeted if the mouse is near it
if text in c.find_overlapping(str(x-10), str(y-10), str(x+10), str(y+10)):
c.coords(text, x, y) # move text to mouse position
c = tk.Canvas(root)
c.pack(anchor='n')
text = c.create_text('10', '10', text='test', fill='red', font=('arial', 18)) # you can define all kinds of text options here
c.bind("<B1-Motion>", change_position)
root.mainloop()

Tkinter, button click with if Statement for a specific picture in a label

I'm trying to do a quiz with 4 pictures given randomly (only one at a time in a label). Below there are 4 buttons which are the answer options. The buttons always stay the same, just the pictures change randomly after answering the right question. So when there is a picture, after pressing the right button the picture should change into another one. If pressing the wrong button, nothing should happen.
So far, the problem is at referring to the picture which is seen at the moment in the right way.
Right now, I tried to change the picture into the next one after answering correctly, because I didn't know how to insert a random change.
Thanks for every help!
from tkinter import *
from random import randint
Fenster = Tk()
Fenster.title('training')
Fenster.geometry('1024x720')
# images
img110 = PhotoImage(file='1.gif')
img120 = PhotoImage(file='2.gif')
img130 = PhotoImage(file='3.gif')
img140 = PhotoImage(file='4.gif')
# Label image
bild=randint(1,4)
if bild==1:
labelbild = Label(image=img110)
elif bild==2:
labelbild = Label(image=img120)
elif bild==3:
labelbild = Label(image=img130)
elif bild==4:
labelbild = Label(image=img140)
labelbild.place(x=350, y=150)
#actions
def button110Click():
if bild==1:
labelbild.config(image=img120)
else:
pass
def button120Click():
if bild==2:
labelbild.config(image=img130)
else:
pass
def button130lick():
if bild==3:
labelbild.config(image=img140)
else:
pass
def button140Click():
if bild==4:
labelbild.config(image=img110)
else:
pass
# Buttons
button110 = Button(master=Fenster, text='108', bg='#D5E88F', command=button110Click)
button110.place(x=350, y=420, width=40, height=40)
button120 = Button(master=Fenster, text='120', bg='#FFCFC9', command=button120Click)
button120.place(x=440, y=420, width=40, height=40)
button130 = Button(master=Fenster, text='128.57', bg='#FBD975', command=button130Click)
button130.place(x=530, y=420, width=40, height=40)
button140 = Button(master=Fenster, text='135', bg='#FBD975', command=button140Click)
button140.place(x=620, y=420, width=40, height=40)
Fenster.mainloop()
I suggest using a list to hold the images, and use bild as the index into this list.
from random import randint
import tkinter
# number of images
N = 4
# Use a Python 'list comprehension' to build a list of images
images = [ PhotoImage(file='%d.gif') % i for i in range(1,N+1)]
bild = 0
def new_image():
# Select and display the an image
global bild
bild = randint(0,N-1)
labelbild = label(images[bild])
labelbild.place(x=350, y=150)
new_image()
# actions
# (I bet there's a parametric way to do this using one function, but I don't know tkinter)
def button110Click():
if bild == 0:
new_image()
def button120Click():
if bild == 1:
new_image()
def button130Click():
if bild == 2:
new_image()
def button140Click():
if bild == 3:
new_image()
# The rest is the same as in the OP.
Since I don't have tkinter I was unable to test the complete application, so there may be bugs.

tkinter label image not updating with .update_idletasks()

I have an issue where my image label will not update. I have used a large combination of root.update() root.update_idletasks() etc, I have also gone through many posts around the internet attempting to use their solutions but to no avail.
I have the code split to one class and two functions, the first function will check if the user has the right spelling or not, the second will pick a new random word and image from a dict.
The issue is that the image will not update, the print command is working so the class and funcs are working fine.
here is the code thus far, I am new to using Class and init I thought the best way to test out the .update of tkinter is a spelling game
from tkinter import *
import random
words = {"apple": "apple.gif", "car": "car.gif"}
MAIN_FONT = "Helvetica", 16
root = Tk()
class mainFrame:
def __init__(self):
self.pick_random = "..."
#MAIN TITLE OF THE APP
main_title = Label(root, text="Spelling", font=MAIN_FONT)
main_title.pack()
#END OF MAIN TITLE
#START OF IMAGE
self.img = PhotoImage(file=self.pick_another() + ".png")
self.show_image = Label(root, image=self.img)
self.show_image.configure(image=self.img)
self.show_image.image = self.img
self.show_image.pack()
#END OF IMAGE
#START OF ENTRY AND BUTTON INPUTS
self.main_entry = Entry(root)
self.submit_btn = Button(root, text="Submit", command=self.submit)
self.main_entry.pack()
self.submit_btn.pack()
#END OF ENTRY AND BUTTON INPUTS
def submit(self):
if self.main_entry.get() == self.pick_random:
print("RIGHT")
self.pick_another()
else:
print("That's not right, try again")
def pick_another(self):
print("Called")
self.pick_random = random.choice(list(words.keys()))
print(self.pick_random)
root.update_idletasks()
return self.pick_random
app = mainFrame()
root.mainloop()
As I said this does kind of work, The first image will show up and inputting the correct spelling for the image will generate a new word but the image does not update.
I have spent a few days working on various scripts trying to get tkinter to update, but it will not.
I would be very grateful for any help in this

Categories

Resources