Python Tkinter按钮高亮显示功能在调用命令后停止工作
我一直在tkinter开发我的第一个GUI——我正在使用Windows。我现在的目标是拥有实现这些目标的按钮:Python Tkinter按钮高亮显示功能在调用命令后停止工作,python,tkinter,Python,Tkinter,我一直在tkinter开发我的第一个GUI——我正在使用Windows。我现在的目标是拥有实现这些目标的按钮: 鼠标悬停在按钮上方时,按钮将高亮显示 如果单击,按钮将保持高亮显示 一次只能“选择”(单击突出显示)一个按钮 我最初以为我已经做到了!但我现在意识到我的工作还没有完成 以下是我所看到的: 我将鼠标移到按钮A上。它将高亮显示!(好) 我点击按钮A。它保持高亮显示!(好) 我将鼠标移到按钮B上。它将高亮显示!(好) 我点击按钮B。它保持高亮显示!将删除A中的高光!(好) 我将鼠标移到按钮A
import tkinter as tk
blue = '#0000BB'
white = '#FFFFFF'
class HoverButton(tk.Button):
def __init__(self, master, position = None, **kw):
tk.Button.__init__(self,master=master,**kw)
self.defaultBackground = self["background"]
self.defaultForeground = self["foreground"]
self.bind("<Enter>", self.on_enter)
self.bind("<Leave>", self.on_leave)
self.bind("<Button-1>", self.hover_click)
self.state = 0
self.position = position
def on_enter(self, e):
if self.state == 0:
self['background'] = self['activebackground']
self['foreground'] = self['activeforeground']
def on_leave(self, e):
if self.state == 2:
self.state = 0
if self.state == 0:
self['background'] = self.defaultBackground
self['foreground'] = self.defaultForeground
def hover_click(self, e):
self.state += 1
self.state = self.state % 3
if self.state == 2:
self['background'] = self.defaultBackground
self['foreground'] = self.defaultForeground
def default_coloring(self):
self['background'] = self.defaultBackground
self['foreground'] = self.defaultForeground
class AddOnFrame(tk.Frame):
def __init__(self, master):
self.selectedbutton = None
super().__init__(master)
games = ['A','B','C']
self.objs = list()
self['bg'] = blue
for i in range(3):
self.objs.append(HoverButton(self,position = i, text = games[i].upper(), activebackground = white,activeforeground = blue,fg = white, bg = blue, borderwidth=0, relief = 'flat', highlightbackground = white))
self.objs[i]['command'] = lambda c=i: self._hover_button_clicked(self.objs[c])
self.objs[i].grid(row = i, column = 0, sticky = tk.W + tk.E)
self.blanklabel = tk.Label(self, text = '', background = white)
self.blanklabel.grid(row = 0, column = 1,rowspan = 10, sticky = tk.N + tk.E + tk.W + tk.S)
self.grid_columnconfigure(1, weight=1, minsize=10)
self.grid_columnconfigure(2, weight=1, minsize=500)
self.grid_columnconfigure(3, weight=1, minsize=500)
self.grid_columnconfigure(4, weight=1, minsize=500)
self.pack(expand = True)
def _hover_button_clicked(self, HoverButton):
self.lastbutton = self.selectedbutton
if self.lastbutton != None:
self.objs[self.lastbutton].default_coloring()
self.selectedbutton = HoverButton.position
window = tk.Tk()
window.geometry('1750x950')
window['bg'] = blue
window.title('Testing')
lf = AddOnFrame(window)
lf['bg'] = blue
window.mainloop()
将tkinter作为tk导入
蓝色=“#0000BB”
白色=“#FFFFFF”
类悬停按钮(tk.Button):
def初始功率(自身、主、位置=无,**kw):
tk.按钮。\uuuuu初始化(自,主=主,**kw)
self.defaultBackground=self[“background”]
self.default前台=self[“前台”]
self.bind(“,self.on_输入)
self.bind(“,self.on_-leave”)
self.bind(“,self.hover\u单击)
self.state=0
self.position=位置
def on_进入(自我,e):
如果self.state==0:
self['background']=self['activebackground']
self['foreground']=self['activeforeground']
休假时的def(自我,e):
如果self.state==2:
self.state=0
如果self.state==0:
self['background']=self.defaultBackground
self['foreground']=self.defaultForeground
def悬停单击(自身,e):
self.state+=1
self.state=self.state%3
如果self.state==2:
self['background']=self.defaultBackground
self['foreground']=self.defaultForeground
def默认颜色(自):
self['background']=self.defaultBackground
self['foreground']=self.defaultForeground
类AddOnFrame(tk.Frame):
定义初始(自我,主):
self.selectedbutton=无
超级()。\uuuu初始化\uuuuu(主)
游戏=['A','B','C']
self.objs=list()
自我['bg']=蓝色
对于范围(3)中的i:
self.objs.append(悬停按钮(self,position=i,text=games[i].upper(),activebackground=white,activeforeground=blue,fg=white,bg=blue,borderwidth=0,relief=flat,highlightbackground=white))
self.objs[i]['command']=lambda c=i:self.\u悬停\u按钮\u单击(self.objs[c])
self.objs[i].grid(行=i,列=0,粘滞=tk.W+tk.E)
self.blanklabel=tk.Label(self,text='',background=white)
self.blanklabel.grid(行=0,列=1,行跨度=10,粘性=tk.N+tk.E+tk.W+tk.S)
self.grid\u columnconfigure(1,权重=1,最小尺寸=10)
self.grid\u columnconfigure(2,重量=1,最小尺寸=500)
self.grid\u columnconfigure(3,重量=1,最小尺寸=500)
self.grid\u columnconfigure(4,重量=1,最小尺寸=500)
self.pack(expand=True)
def_悬停按钮_单击(自身,悬停按钮):
self.lastbutton=self.selectedbutton
如果self.lastbutton!=无:
self.objs[self.lastbutton]。默认颜色()
self.selectedbutton=HoverButton.position
window=tk.tk()
window.geometry('1750x950'))
窗口['bg']=蓝色
window.title(“测试”)
lf=附加框架(窗口)
lf['bg']=蓝色
window.mainloop()
粗略检查后,这一顺序似乎是问题所在:
- 单击按钮时,
方法被调用AddOnFrame.\u hover\u按钮\u单击
最初是AddOnFrame.selectedbutton
,这意味着None
中的if语句将不可用 第一次执行。这就是为什么按钮似乎能正常工作的原因 第一次单击它们时,但不是之后AddOnFrame.\u hover\u button\u clicked
- 但是,下次调用时(下次调用按钮时
按下),
不是AddOnFrame。selectedbutton
,并且永远不会 再次成为None
,这意味着从现在起,每次单击都将导致 调用None
的悬停按钮
方法默认着色
会在单击按钮后立即调用,该按钮 导致从活动颜色快速闪烁为默认颜色, 并且按钮不会一直高亮显示default\u coloring
default\u着色
之类的事情。它对你的伤害似乎大于帮助。我不太清楚你为什么要这么做(设置命令、lambda、整个\u hover\u按钮\u clicked
方法的所有内容),因为当调用on\u leave
或hover\u click
时,按钮似乎正在将颜色设置回默认值。您可以通过更改鼠标悬停按钮的主体来解决问题。默认的\u着色功能如下:
def default_coloring(self):
return
真正的解决办法是对代码进行一些重组
编辑我提供此功能是为了帮助您简化工作:
import tkinter as tk
colors = {
"white": "#FFFFFF",
"blue": "#0000BB"
}
class HoverButton(tk.Button):
def __init__(self, *args, **kwargs):
tk.Button.__init__(self, *args, **kwargs)
self.is_selected = False
self.is_highlighted = False
self["borderwidth"] = 0
self["relief"] = tk.FLAT
self["font"] = ("United Sans Cd Bk", 30)
self["activeforeground"] = colors["blue"]
self["activebackground"] = colors["white"]
self["highlightbackground"] = colors["white"]
self.recolor()
self.bind("<Enter>", self.on_enter)
self.bind("<Leave>", self.on_leave)
self.bind("<Button-1>", self.on_click)
def recolor(self):
self["background"] = [colors["blue"], colors["white"]][self.is_highlighted]
self["foreground"] = [colors["white"], colors["blue"]][self.is_highlighted]
def on_enter(self, *args):
self.is_highlighted = True
self.recolor()
def on_leave(self, *args):
if self.is_selected:
return
self.is_highlighted = False
self.recolor()
def on_click(self, *args):
self.is_selected = not self.is_selected
class Application(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title("Window")
self.geometry("256x256")
self.resizable(width=False, height=False)
self["background"] = colors["blue"]
button_labels = ["A", "B", "C"]
self.buttons = []
for row, button_label in enumerate(button_labels):
button = HoverButton(text=button_label)
button.grid(row=row, column=0, sticky=tk.W)
self.buttons.append(button)
def main():
application = Application()
application.mainloop()
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
def default_coloring(self):
self.state = 0
self['background'] = self.defaultBackground
self['foreground'] = self.defaultForeground
def _hover_button_clicked(self, HoverButton):
self.lastbutton = self.selectedbutton
if (self.lastbutton != None) and (self.lastbutton != HoverButton.position):
self.objs[self.lastbutton].default_coloring()
self.selectedbutton = HoverButton.position