Reputation: 1
I have created a simple Tkinter application with a canvas widget like this:
from tkinter import *
root = Tk()
root.geometry("500x500-500+500")
canvas = Canvas(root, width = 400, height = 400, bg = "white")
canvas.pack()
canvas.create_line(0, 0, 200, 100, width = 20, fill = "black")
root.mainloop()
My question is, how can I get the color of the canvas in a specific position? Say for instance I clicked somewhere on the line, how can I get back the color "black" from that?
In other words, if I wanted a function like this,
def getColor(cnvs, event = None):
x = event.x
y = event.y
# somehow gets the color of cnvs at position (x, y) and stores it as color
return color
how would I go about doing that?
Upvotes: 0
Views: 1973
Reputation: 21
I tried the PIL ImageGrab approach today and found that ImageGrab on a Mac returned the screen background, not tkinter or canvas contents.
Here's a solution that works, at least on a Mac running Monterrey
Use the tkinter.colorchooser dialog. See: https://docs.python.org/3/library/tkinter.colorchooser.html
The dialog displays the system color picker and returns a tuple containing an rgb tuple and a string usable as a color in tkinter.
At least on a Mac, the color picker includes an eye dropper that works on the canvas (or anywhere on your screen).
I don't know whether the same is available in Windows.
Here's a fairly short demo program. Run the program, click the button, then select the eyedropper in the color picker (you also have to click "OK" in the color picker.
# ColorChooserDemo.py
import tkinter as tk
from tkinter import colorchooser
class EyeDropperDemo(tk.Tk):
def __init__(self):
super().__init__()
canvas = tk.Canvas(self, bg='gray', width=200, height=120)
canvas.pack()
canvas.create_rectangle(40, 40, 80, 80, fill='red')
canvas.create_rectangle(120, 40, 160, 80, fill='blue')
tk.Button(self, text='Color Picker', command=self.eyedropper).pack()
def eyedropper(self):
color: None | tuple[tuple, str] = tk.colorchooser.askcolor()
print(f'askcolor() returned {color}')
if color is not None:
tkinter_color = color[1]
tk.Label(self, text=f'You Picked {tkinter_color}', bg=tkinter_color).pack()
if __name__ == '__main__':
app = EyeDropperDemo()
app.mainloop()
Upvotes: 0
Reputation: 47183
You can take a screen shot of the canvas using Pillow.ImageGrab
module and get the required pixel color from the snapshot image:
from PIL import ImageGrab
def get_color(cnvs, event):
x, y = cnvs.winfo_rootx()+event.x, cnvs.winfo_rooty()+event.y
# x, y = cnvs.winfo_pointerx(), cnvs.winfo_pointery()
image = ImageGrab.grab((x, y, x+1, y+1)) # 1 pixel image
return image.getpixel((0, 0))
Note that the color returned is in (R, G, B)
format.
Upvotes: 1