繁体   English   中英

为多种颜色的Tkinter按钮着色

[英]Color a Tkinter button in multiple colors

我试图在Tkinter的一个按钮上放置多种颜色。 这就是我想出的:

from Tkinter import *
master = Tk()
buttons = {}

def press(clicked):
    print clicked
    return
for i in range(1,7):
    button_name = 'button '+str(i)
    buttons[i] = Button(master, text=button_name, command=lambda method=button_name:press(method))
    buttons[i].grid(row=0, column=i-1, padx=15)
    buttons[i].update()

    tot_x = buttons[i].winfo_width()
    tot_y = buttons[i].winfo_height()

    redframe = Frame(buttons[i], width=tot_x/6, background='red')
    blueframe = Frame(buttons[i], width=tot_x/6*5, background='blue')

    redframe.place(x=0, y=0, relheight=1)
    blueframe.place(relx=1./6, y=0, relheight=1)

master.mainloop()

问题在于它使按钮几乎不可点击,因为框架会以某种方式干扰按钮的“可点击性”。 当光标放在它们的位置时,彩色框架也会突然消失。

有没有办法让这些框架留在按钮上并使它们不能停止点击?

可以说,最简单的方法可能是使用您想要的颜色创建图像,然后使用按钮中的图像和文本。

虽然我认为Bryan的答案更简单并且完全解决了问题,但您可以解决绑定的“可点击性”问题(我没有遇到第二个问题,所以我的答案没有解决它)。

我们的想法是在框架上绑定鼠标点击以触发按钮上的单击并恢复通常的按钮行为。 在下面的示例中,我绑定了<ButtonPress-1><ButtonRelease-1>以查看按钮缓解效果。 我还绑定了<Enter><Leave>以在鼠标悬停时实现按钮颜色更改。

from Tkinter import *
master = Tk()
buttons = {}

def press(clicked):
    print clicked

def frame_enter(redframe, blueframe):
    redframe.configure(background='coral1')
    blueframe.configure(background='royalblue1')

def frame_leave(redframe, blueframe):
    redframe.configure(background='red')
    blueframe.configure(background='blue')

def on_press(event, button):
    button.event_generate('<ButtonPress-1>', x=event.x, y=event.y)

def on_release(event, button):
    button.event_generate('<ButtonRelease-1>', x=event.x, y=event.y)

for i in range(1,7):
    button_name = 'button '+str(i)
    buttons[i] = Button(master, text=button_name, command=lambda method=button_name:press(method))
    buttons[i].grid(row=0, column=i-1, padx=15)
    buttons[i].update()

    tot_x = buttons[i].winfo_width()
    tot_y = buttons[i].winfo_height()

    redframe = Frame(buttons[i], width=tot_x/6, background='red')
    blueframe = Frame(buttons[i], width=tot_x/6*5, background='blue')

    redframe.place(x=0, y=0, relheight=1)
    blueframe.place(relx=1./6, y=0, relheight=1)
    redframe.bind('<ButtonPress-1>', lambda e, b=buttons[i]: on_press(e, b)) 
    blueframe.bind('<ButtonPress-1>', lambda e, b=buttons[i]: on_press(e, b)) 
    redframe.bind('<ButtonRelease-1>', lambda e, b=buttons[i]: on_release(e, b)) 
    blueframe.bind('<ButtonRelease-1>', lambda e, b=buttons[i]: on_release(e, b)) 
    redframe.bind('<Enter>', lambda e, rf=redframe, bf=blueframe: frame_enter(rf, bf)) 
    blueframe.bind('<Enter>', lambda e, rf=redframe, bf=blueframe: frame_enter(rf, bf)) 
    redframe.bind('<Leave>', lambda e, rf=redframe, bf=blueframe: frame_leave(rf, bf)) 
    blueframe.bind('<Leave>', lambda e, rf=redframe, bf=blueframe: frame_leave(rf, bf)) 

master.mainloop()

编辑:不需要保持按钮,可以用框架替换它们。 这样,不需要使用place ,彩色框架可以只包装在里面:

from Tkinter import *
master = Tk()
buttons = {}

def press(clicked):
    print clicked

def frame_enter(redframe, blueframe):
    redframe.configure(background='coral1')
    blueframe.configure(background='royalblue1')

def frame_leave(redframe, blueframe):
    redframe.configure(background='red')
    blueframe.configure(background='blue')

def on_press(event, widget):
    widget.configure(relief='sunken')  # mimic button's relief effect on click 

def on_release(event, widget, text):
    widget.configure(relief='raised')  # mimic button's relief effect on click 
    press(text)

for i in range(1,7):
    button_name = 'button '+ str(i)
    buttons[i] = Frame(master, relief='raised', width=78, height=24, bd=2)
    buttons[i].grid(row=0, column=i-1, padx=15)
    buttons[i].update_idletasks()

    tot_x = buttons[i].winfo_width()
    tot_y = buttons[i].winfo_height()

    redframe = Frame(buttons[i], width=tot_x/6, height=tot_y, background='red')
    blueframe = Frame(buttons[i], width=tot_x/6*5, height=tot_y, background='blue')

    redframe.pack(side='left')
    blueframe.pack(side='left')
    redframe.bind('<ButtonPress-1>', lambda e, b=buttons[i]: on_press(e, b)) 
    blueframe.bind('<ButtonPress-1>', lambda e, b=buttons[i]: on_press(e, b)) 
    redframe.bind('<ButtonRelease-1>', lambda e, b=buttons[i], t=button_name: on_release(e, b, t)) 
    blueframe.bind('<ButtonRelease-1>', lambda e, b=buttons[i], t=button_name: on_release(e, b, t)) 
    redframe.bind('<Enter>', lambda e, rf=redframe, bf=blueframe: frame_enter(rf, bf)) 
    blueframe.bind('<Enter>', lambda e, rf=redframe, bf=blueframe: frame_enter(rf, bf)) 
    redframe.bind('<Leave>', lambda e, rf=redframe, bf=blueframe: frame_leave(rf, bf)) 
    blueframe.bind('<Leave>', lambda e, rf=redframe, bf=blueframe: frame_leave(rf, bf)) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM