Python2.7Tkinter:如何在鼠标下按键配置形状

Python2.7Tkinter:如何在鼠标下按键配置形状,python,python-2.7,tkinter,tkinter-canvas,Python,Python 2.7,Tkinter,Tkinter Canvas,基本上,我有一个程序,可以在画布上创建圆圈,使用滑块小部件获取rgb值,并在侧面显示所述颜色的十六进制值。我想做的是,如果用户不喜欢颜色,可以将鼠标悬停在形状上,然后按“r”键直接更改形状的颜色鼠标光标下的形状,如果滑块改变了形状,则该形状现在由滑块生成。 迄今为止的代码: import Tkinter root = Tkinter.Tk() root.wm_title('Hexadecimal Explorer') red_intvar = Tkinter.IntVar() red_in

基本上,我有一个程序,可以在画布上创建圆圈,使用滑块小部件获取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()
导入Tkinter
root=Tkinter.Tk()
root.wm_标题(“十六进制资源管理器”)
red_intvar=Tkinter.intvar()
红色内部变量集(127)
blue_intvar=Tkinter.intvar()
蓝色内部变量集(127)
green_intvar=Tkinter.intvar()
绿色变量集(127)
def颜色已更改(新版本):
editor.insert(Tkinter.END,“#”+hexstring(red#u intvar)+hexstring(green#u intvar)+hexstring(blue#u intvar)+“\n”)
编辑器。请参见(Tkinter.END)
颜色='#'+hexstring(红色)和hexstring(绿色)和hexstring(蓝色)
canvas=Tkinter.canvas(根,宽=300,高=300,背景='#FFFFFF')
网格(行=0,行跨度=4,列=2)
红色滑块=Tkinter.Scale(根,从0到255,变量=红色intvar,
方向=Tkinter.水平,
label='Red',command=颜色(已更改)
红色滑块.grid(行=1,列=0,粘性=Tkinter.E)
蓝色滑块=Tkinter.Scale(根,从0到255,变量=蓝色intvar,
方向=Tkinter.水平,
label='Blue',command=颜色(已更改)
蓝色滑块.grid(行=2,列=0,粘性=Tkinter.E)
绿色滑块=Tkinter.Scale(根,从=0到=255,变量=green\u intvar,
方向=Tkinter.水平,
标签=“绿色”,命令=颜色(已更改)
绿色滑块网格(行=3,列=0,粘性=Tkinter.E)
text=Tkinter.Label(根,text='拖动滑块\n以调整\n颜色代码!')
text.grid(行=0,列=0)
编辑器=Tkinter.Text(根,宽度=10)
网格编辑器(列=1,行=0,行跨度=4)
def关闭(事件):
全球startx,starty
startx=event.x
starty=event.y
形状=[]
def up(事件):
tk\u color\u string=color(红色、绿色、蓝色)
r=(startx event.x)**2+(starty event.y)**2#毕达哥拉斯定理
r=int(r**.5)#求距离的平方根
新建形状=画布。创建椭圆形(startx-r、starty-r、startx+r、starty+r、,
fill=tk_color_字符串,轮廓='#000000')
shapes.append(新的_形状)
画布绑定(“”,向下)
画布绑定(“”,向上)
def回收(事件):
startx=event.x
starty=event.y
tk\u color=颜色(红色、绿色、蓝色)
canvas.itemconfig(event.widget.find_closest(startx,starty),fill=tk_color)
canvas.bind('r',recolor)
def hexstring(滑块\u intvar):
slider\u int=slider\u intvar.get()
滑块\十六进制=十六进制(滑块\整数)
滑块\十六进制\数字=滑块\十六进制[2:]
如果len(滑块十六进制数字)==1:
滑块\u十六进制\u数字='0'+滑块\u十六进制\u数字
返回滑块\u十六进制\u数字
def颜色(r、g、b):
rx=十六进制字符串(r)
gx=十六进制字符串(g)
bx=十六进制字符串(b)
返回“#”+rx+gx+bx
root.mainloop()
我觉得这是一个简单的解决办法,但已经研究了这个问题,并没有找到太多关于它,谢谢你的时间

canvas.bind('r', recolor)
问题就在这里。通常,画布对象从不接收键盘焦点,因此将键盘快捷键绑定到画布对象没有任何效果

您可以使用
focus\u set
强制画布具有焦点。这样做的逻辑位置是鼠标单击回调

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

或者,尝试绑定到根窗口。这将更改
事件
对象的内容,因此您需要直接在
itemconfig
行上参考
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)

你的问题是什么?看来你是在要求我们为你实施这项计划。你正在努力解决的问题是否有一个具体的部分?实际的问题似乎是“……但当我按R键时,椭圆形的颜色没有改变,什么都没有发生”。Byran的问题是,我似乎无法让圆形改变颜色,我不知道如何找到形状(椭圆形)在画布中,无需鼠标点击,因为我希望用户能够按下按钮来执行此操作,我会看到点击会产生更多问题,因为点击会生成一个新的形状。这有助于解决此问题。不过,我使用了另一个鼠标运动绑定来获得startx和starty,因此鼠标位置始终保持不变众所周知,感谢您的帮助绑定到根窗口将影响每个小部件,包括文本和条目小部件。更好的解决方案是只给画布键盘焦点。@BryanOakley,我考虑过,但我决定不这样做,因为我认为拖动滑块会导致画布再次失去焦点,这会很不方便。但现在我看到滑块不会以这种方式窃取焦点,所以
focus\u set
应该可以正常工作。编辑。