Python2.7Tkinter:如何在鼠标下按键配置形状
基本上,我有一个程序,可以在画布上创建圆圈,使用滑块小部件获取rgb值,并在侧面显示所述颜色的十六进制值。我想做的是,如果用户不喜欢颜色,可以将鼠标悬停在形状上,然后按“r”键直接更改形状的颜色鼠标光标下的形状,如果滑块改变了形状,则该形状现在由滑块生成。 迄今为止的代码: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
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
应该可以正常工作。编辑。