Python 2.7 Tkinter:如何通过按键配置鼠标下方的形状

Python 2.7 Tkinter: How would I config the shape under the mouse with key press

基本上我有一个程序在 canvas 上创建圆圈,滑块小部件获取 rgb 值,旁边的文本框显示所述颜色的十六进制值,我想要做的是得到这个如果用户不喜欢颜色,他们可以将鼠标悬停在形状上,然后按 'r' 键将鼠标光标正下方的形状颜色更改为现在使用滑块制作的形状(如果滑块更改)它。 到目前为止的代码:

import Tkinter

root = Tkinter.Tk()
root.wm_title('Hexadecimal Explorer')

red_intvar = Tkinter.IntVar() 
red_intvar.set(127)
blue_intvar = Tkinter.IntVar() 
blue_intvar.set(127)
green_intvar = Tkinter.IntVar()
green_intvar.set(127)

def color_changed(new_intval):
    editor.insert(Tkinter.END, '#' + hexstring(red_intvar) + hexstring(green_intvar) + hexstring(blue_intvar) + '\n')
    editor.see(Tkinter.END)
    color = '#' + hexstring(red_intvar) + hexstring(green_intvar) + hexstring(blue_intvar)
canvas = Tkinter.Canvas(root, width=300, height=300, background='#FFFFFF')
canvas.grid(row=0, rowspan=4, column=2)

red_slider = Tkinter.Scale(root, from_=0, to=255, variable=red_intvar, 
                       orient=Tkinter.HORIZONTAL,   
                       label='Red', command=color_changed)
red_slider.grid(row=1, column=0, sticky=Tkinter.E)

blue_slider = Tkinter.Scale(root, from_=0, to=255, variable=blue_intvar, 
                       orient=Tkinter.HORIZONTAL,   
                       label='Blue', command=color_changed)
blue_slider.grid(row=2, column=0, sticky=Tkinter.E)

green_slider = Tkinter.Scale(root, from_=0, to=255, variable=green_intvar,  
                         orient=Tkinter.HORIZONTAL,
                         label='Green', command=color_changed)
green_slider.grid(row=3, column=0, sticky=Tkinter.E)

text = Tkinter.Label(root, text='Drag slider \nto adjust\ncolor code.')
text.grid(row=0, column=0)

editor = Tkinter.Text(root, width=10)
editor.grid(column=1, row=0, rowspan=4)

def down(event):
    global startx, starty 
    startx = event.x 
    starty = event.y
shapes = []
def up(event):
    tk_color_string = color(red_intvar, green_intvar, blue_intvar)
    r = (startx-event.x)**2 + (starty-event.y)**2  # Pythagorean theorem
    r = int(r**.5)                                 # square root to get distance
    new_shape = canvas.create_oval(startx-r, starty-r, startx+r, starty+r,
                                fill=tk_color_string, outline='#000000')
    shapes.append(new_shape)

canvas.bind('<Button-1>', down)
canvas.bind('<ButtonRelease-1>', up)

def recolor(event):
    startx = event.x
    starty = event.y
    tk_color = color(red_intvar, green_intvar, blue_intvar)
    canvas.itemconfig(event.widget.find_closest(startx, starty), fill=tk_color)
canvas.bind('r', recolor)

def hexstring(slider_intvar):
    slider_int = slider_intvar.get()
    slider_hex = hex(slider_int)
    slider_hex_digits = slider_hex[2:] 
    if len(slider_hex_digits)==1:
        slider_hex_digits = '0' + slider_hex_digits 
    return slider_hex_digits

def color(r,g,b):
    rx=hexstring(r)
    gx=hexstring(g)
    bx=hexstring(b)
    return '#'+rx+gx+bx
root.mainloop()

我觉得这很容易解决,但研究了这个问题,但找不到太多相关信息,谢谢您的宝贵时间。

canvas.bind('r', recolor)

问题来了。通常,Canvas 对象永远不会获得键盘焦点,因此将键盘快捷键绑定到它们是无效的。

您可以使用 focus_set 强制 canvas 获得焦点。一个合乎逻辑的地方是在你的鼠标点击回调中。

def down(event):
    global startx, starty 
    startx = event.x 
    starty = event.y
    canvas.focus_set()

或者,尝试绑定到根 window。不过,这会更改 event 对象的内容,因此您需要直接在 itemconfig 行上引用 canvas,并做一些额外的运算来找到鼠标的位置相对于 canvas.

def recolor(event):
    startx = event.x - canvas.winfo_x()
    starty = event.y - canvas.winfo_y()
    tk_color = color(red_intvar, green_intvar, blue_intvar)
    canvas.itemconfig(canvas.find_closest(startx, starty), fill=tk_color)
root.bind('r', recolor)