我正在使用Tkinter的"place"函数创建一些按钮。我想让它们在用户悬停在上面时显示为灰色,然后在光标离开时返回黑色。我可以通过显式绑定它们来实现这一点,但我希望通过循环动态绑定它们。我试图创建的循环位于代码的底部,但它不起作用。
如果你想看看我在说什么,这段代码将在python中运行。
如何创建一个动态循环来执行此操作?
from tkinter import *
FONT_SIZE = 14 # Change this to change all font sizes in the program
root = Tk()
root.resizable(width=TRUE, height=TRUE)
root.geometry("800x600")
root.config(background="black")
# Labels
newGameButton = Label(root)
loadGameButton = Label(root)
optionsButton = Label(root)
exitButton = Label(root)
Labels = [newGameButton, loadGameButton, optionsButton, exitButton]
#Changes the background of buttons when you hover over them
def changeBGEnter(widget):
widget.config(background="gray")
#Changes the background of buttons when you stop hovering them
def changeBGLeave(widget):
widget.config(background="black")
# Explicit bindings, ugly
newGameButton.bind("<Enter>", lambda x: changeBGEnter(newGameButton))
newGameButton.bind("<Leave>", lambda x: changeBGLeave(newGameButton))
loadGameButton.bind("<Enter>", lambda x: changeBGEnter(loadGameButton))
loadGameButton.bind("<Leave>", lambda x: changeBGLeave(loadGameButton))
optionsButton.bind("<Enter>", lambda x: changeBGEnter(optionsButton))
optionsButton.bind("<Leave>", lambda x: changeBGLeave(optionsButton))
exitButton.bind("<Enter>", lambda x: changeBGEnter(exitButton))
exitButton.bind("<Leave>", lambda x: changeBGLeave(exitButton))
# New Game Button
newGameButton.config(
anchor=CENTER, # Where to anchor the text in the widget
background="black",
foreground="white",
font=("default", FONT_SIZE),
text="NewGame",
)
newGameButton.place(
relwidth=0.6,
relheight=0.1,
relx=0.2,
rely=0.3
)
# Load Game Button
loadGameButton.config(
anchor=CENTER,
background="black",
foreground="white",
font=("default", FONT_SIZE),
text="Stats",
)
loadGameButton.place(
relwidth=0.6,
relheight=0.1,
relx=0.2,
rely=0.4
)
# Options Button
optionsButton.config(
anchor=CENTER,
background="black",
foreground="white",
font=("default", FONT_SIZE),
text="Output",
)
optionsButton.place(
relwidth=0.6,
relheight=0.1,
relx=0.2,
rely=0.5
)
# Exit Button
exitButton.config(
anchor=CENTER,
background="black",
foreground="white",
font=("default", FONT_SIZE),
text="Exit",
)
exitButton.place(
relwidth=0.6,
relheight=0.1,
relx=0.2,
rely=0.6
)
#Code I want that doesn't work:
#Get rid of explicit bindings above to test the code below
"""
for x in Labels:
x.bind("<Enter>", lambda x: changeBGEnter(x))
x.bind("<Leave>", lambda x: changeBGLeave(x))
"""
root.mainloop()
-
bind发送
event data
作为lambda
中的第一个参数,因此x
是event data
,而不是标签。 -
(在
for
循环中)lambda不会将值从lab
复制到changeBGEnter(lab)
(但使用lab
作为参考,所有changeBGEnter
都得到相同的最后一个标签),因此您必须使用label=lab
复制它
for lab in Labels:
lab.bind("<Enter>", lambda event, label=lab: changeBGEnter(label))
lab.bind("<Leave>", lambda event, label=lab: changeBGLeave(label))
-
(顺便说一句:你可以创建自己的小部件来简化它)
编辑:自己的小部件MyButton
,带有绑定的<Enter>
和<Leave>
from tkinter import *
class MyButton(Label):
def __init__(self, *args, **kwargs):
Label.__init__(self, *args, **kwargs)
self.bind("<Enter>", self.changeBGEnter)
self.bind("<Leave>", self.changeBGLeave)
def changeBGEnter(self, event):
self.config(background="gray")
def changeBGLeave(self, event):
self.config(background="black")
FONT_SIZE = 14 # Change this to change all font sizes in the program
root = Tk()
root.resizable(width=TRUE, height=TRUE)
root.geometry("800x600")
root.config(background="black")
# Labels
newGameButton = MyButton(root)
loadGameButton = MyButton(root)
optionsButton = MyButton(root)
exitButton = MyButton(root)
Labels = [newGameButton, loadGameButton, optionsButton, exitButton]
# New Game Button
newGameButton.config(
anchor=CENTER, # Where to anchor the text in the widget
background="black",
foreground="white",
font=("default", FONT_SIZE),
text="NewGame",
)
newGameButton.place(
relwidth=0.6,
relheight=0.1,
relx=0.2,
rely=0.3
)
# Load Game Button
loadGameButton.config(
anchor=CENTER,
background="black",
foreground="white",
font=("default", FONT_SIZE),
text="Stats",
)
loadGameButton.place(
relwidth=0.6,
relheight=0.1,
relx=0.2,
rely=0.4
)
# Options Button
optionsButton.config(
anchor=CENTER,
background="black",
foreground="white",
font=("default", FONT_SIZE),
text="Output",
)
optionsButton.place(
relwidth=0.6,
relheight=0.1,
relx=0.2,
rely=0.5
)
# Exit Button
exitButton.config(
anchor=CENTER,
background="black",
foreground="white",
font=("default", FONT_SIZE),
text="Exit",
)
exitButton.place(
relwidth=0.6,
relheight=0.1,
relx=0.2,
rely=0.6
)
root.mainloop()
编辑:但您可以使用tkinter.Button
来获得相同的结果,而无需自己的小部件或循环。
您可以使用command=
为按钮点击分配功能。
exitButton = Button(root)
def command_exit():
print "exit"
root.destroy()
exitButton.config(
anchor=CENTER,
font=("default", FONT_SIZE),
text="Exit",
# Leave colors
background="black",
foreground="white",
# without border
borderwidth=0,
highlightthickness=0,
# Enter colors
activebackground="grey",
activeforeground="white",
# run on click
command=command_exit
)