Python Forum
An interactive image that allows a selection of a specific point
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
An interactive image that allows a selection of a specific point
#1
Hi all,

I am creating a program/script that displays an image of a product with several hundred screw positions. I have a separate list of the coordinates in relation to the upper left corner of the image, and the size of the product in question.

What I am trying to achieve via python is to find a way to link my list of coordinates to this image in the way that a person can "select" a coordinate (in this case a screw) by clicking on it. Then I further process this information later in the script.

I did some googling and saw that there are multiple ways to approach this, but I'd like to know what would be the "least" stressful way.

See attachment for visual presentation of the question.    
Reply
#2
I would make each of the clickable images a button. If only one image can be clicked at a time I would put all the buttons in a radio cluster/button group
Reply
#3
This might help you. lines 3 to 5 create a function that is called whenever the number one mouse button is clicked inside of the Tkinter Canvas. On line 4 it checks the co-ordinates of the mouse when it was clicked as event.y and event.x. On line number nine the mouse is 'bound' to the canvas and this is what causes clicked () to be called whenever the mouse is clicked. The rest of the code is just drawing the circles on the canvas.

You can load your photo onto the canvas and use a list of the co-ordinates to test if the mouse was on one of the screws when it was clicked. Let us know if you need help with that. Have fun Smile

from tkinter import Tk, Canvas, mainloop

def clicked (event) :
	button_number = (int (event.y / 60) * 9) + (1 + int (event.x / 60))
	print (f'You clicked button number {button_number}.')

root = Tk ()
drawCanv = Canvas (width = 541, height = 301, bd = 0)
drawCanv.bind ('<Button-1>', clicked)

button_number = 1
for y in range (1, 300, 60) :
	for x in range (1, 540, 60) :
		rectangle = drawCanv.create_oval (x, y, x + 60, y + 60,\
			outline = 'black')  
		drawCanv.create_text (x + 25, y + 30, text = button_number)
		button_number += 1
drawCanv.pack ()

mainloop ()
Reply
#4
Great, thank you, guys; progress has been made!

I went with the TKinter route where I display the image, and then create buttons on top of the image. This works well, but I have some issues having the buttons do what I want on click.

What I am doing now (mainly for testing purposes) is that I create dictionary with different button variables that should assign an image, and a command to each button. When this button is pressed the button image should change. This does not happen. There is probably a lot wrong with my code, but at least it displays the initial buttons nicely! Any suggestions on how to move forward?

An image displayed in TKinter as attachment. All the red circles are buttons.

button_up = Image.open((r"C:\Users\ezsaksa\Desktop\code\images_red.jpg"))
button_down = Image.open((r"C:\Users\ezsaksa\Desktop\code\images_green.jpg"))
b_t_size = [9, 9]

button_up.thumbnail((b_t_size[0],b_t_size[1]))
button_down.thumbnail((b_t_size[0],b_t_size[1]))
button_up = ImageTk.PhotoImage(button_up)
button_down = ImageTk.PhotoImage(button_down)

def PlayButtonDown():
    
   button_dict["Button" + str(i)] = tk.Button(image = button_down, command = lambda i = i: PlayButtonUp())
   button_dict["Button" + str(i)].update()
   return button_dict

def PlayButtonUp():

    button_dict["Button" + str(i)] = tk.Button(image = button_up, command = lambda i = i: PlayButtonDown())
    button_dict["Button" + str(i)].update()
    return button_dict 

button_dict = {}

while i < len(co_list):
   
    button_dict["Button" + str(i)] = tk.Button(image = button_up, command = lambda i = i: PlayButtonDown())
    button_dict["Button" + str(i)]["bg"] = "white"
    button_dict["Button" + str(i)]["border"] = "0"
    button_dict["Button" + str(i)].place(x=float(1.393)*co_list[i][0]-b_t_size[0]/2, y=float(1.392)*co_list[i][1]-b_t_size[1]/2)
    i += 1

root.mainloop()

Attached Files

Thumbnail(s)
   
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  "Interactive" figure in a GUI puje 2 4,567 Jun-24-2020, 06:55 PM
Last Post: puje
  python interactive output with Qt4 eegrek39 8 5,041 Mar-18-2018, 08:41 PM
Last Post: eegrek39

Forum Jump:

User Panel Messages

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