问题
I have been working on a Python/Tkinter project that requires programatically created buttons from a list as below.
When a certain button is pressed, I would like that button to become "sunken"
until another button is pressed, at that stage that button would become "sunken"
, and the button first clicked would become 'normal'
.
So far I can't figure out how to do this without having to code each button individually.
Ideally the relief
would be set in the press()
function.
import tkinter
window = tkinter.Tk()
window.title("Practice UI")
window.grid()
numbers = ["1","2","3","4","5","6","7","8","9"]
def buttonCreator(labels):
n = 0
button = []
for x in range(0,3):
for y in range(0,3):
if n<=len(labels)-1:
button.append(tkinter.Button(window, text = labels[n], command = lambda x = labels[n]:press(x)))
button[n].grid(row = x, column = y)
n +=1
def press(value):
print(value)
buttonCreator(numbers)
window.mainloop()
回答1:
You could simply return button
and use it to access your buttons in press()
:
import tkinter
window = tkinter.Tk()
window.grid()
# changed to integers so we can loop through the
# values in press() and use them as indices
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
def buttonCreator(labels):
n = 0
button = []
for x in range(0, 3):
for y in range(0, 3):
if n <= len(labels) - 1:
button.append(tkinter.Button(window, text=labels[n],
command=lambda x=labels[n]:press(x)))
button[n].grid(row=x, column=y)
n += 1
return button # added a return statement
def press(value):
for x in numbers:
# index is x-1 because 1 is in button[0], etc
button[x-1]['relief'] = 'sunken' if x == value else 'raised'
button = buttonCreator(numbers)
window.mainloop()
回答2:
You are describing the behavior of a group of radiobuttons so you should use those.
Conveniently radiobuttons have an attribute indicatoron
which
Normally a radiobutton displays its indicator. If you set this option to zero, the indicator disappears, and the entire widget becomes a “push-push” button that looks raised when it is cleared and sunken when it is set. You may want to increase the borderwidth value to make it easier to see the state of such a control.
thus, when set to zero it does precisely what you request.
回答3:
Just for an example, I'll create two buttons with the reaction you wanted:
from Tkinter import *
win = Tk()
def press1():
button1["relief"] = "sunken"
button2["relief"] = "normal"
def press2():
button1["relief"] = "normal"
button2["relief"] = "sunken"
button1 = Button(win, text="Button 1", command=press1)
button2 = Button(win, text="Button 2", command=press2)
button1.pack()
button2.pack()
button1.grid(row=1, column=1)
button2.grid(row=1, column=2)
win.mainloop()
Should work. A second way:
from Tkinter import *
win = Tk()
def press(buttonnumber):
if buttonnumber==1:
button1["relief"] = "sunken"
button2["relief"] = "normal"
elif buttonnumber==2:
button1["relief"] = "normal"
button2["relief"] = "sunken"
else:
raise Exception("No Button Number \"%d\"" % buttonnumber)
button1 = Button(win, text="Button 1", command=lambda: press(1))
button2 = Button(win, text="Button 2", command=lambda: press(2))
button1.pack()
button2.pack()
button1.grid(row=1, column=1)
button2.grid(row=1, column=2)
win.mainloop()
来源:https://stackoverflow.com/questions/31497374/how-to-associate-the-same-operation-to-a-set-of-buttons-programmatically-in-tkin