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

时间:2015-10-27 12:20:54

标签: python python-2.7 tkinter tkinter-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()

我觉得这是一个简单的解决方案,但是研究这个问题并且找不到它,谢谢你的时间。

1 个答案:

答案 0 :(得分:1)

canvas.bind('r', recolor)

这是问题所在。通常,Canvas对象永远不会接收键盘焦点,因此将键盘快捷键绑定到它们无效。

您可以使用focus_set强制画布获得焦点。这样做的合理位置是鼠标点击回调。

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

或者,尝试绑定到根窗口。这将改变event对象的内容,因此您需要直接在canvas行上引用itemconfig,并进行一些额外的算术来查找鼠标的位置相对于画布。

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)