我正在尝试创建一个程序,该程序允许用户选择任意数量的复选框,然后单击按钮以从这些复选框中返回随机结果。由于我的名单基于Smash bros Ultimate的名单,因此我尽量避免创建70多个变量来放置复选框。但是,我无法弄清楚如何进行迭代。在我弄清楚之前,为行设置的各种值只是占位符。我还希望在顶部有一个重置按钮,该按钮使用户可以自动取消选中每个复选框。到目前为止,这是我的代码。任何帮助将不胜感激。
#!/usr/bin/python3
from tkinter import *
window = Tk()
#window name and header
window.title("Custom Random SSBU")
lbl = Label(window, text="Select the fighters you would like to include:")
lbl.grid(column=1, row=0)
f = [] #check boxes
ft = open("Fighters.txt").readlines() #list of all the character names
fv=[0]*78 #list for tracking what boxes are checked
ff=[] #list to place final character strings
def reset():
for i in fv:
fv[i]=0
rst = Button(window, text="Reset", command=reset)
rst.grid(column=0, row=3)
for y in range (0,77):
f[y] = Checkbutton(window, text = ft[y], variable = fv[y])
f[y].grid(column=0, row=4+y)
def done():
for j in fv:
if fv[j] == 1:
ff.append(fv[j])
result = random.choice(ff)
r=Label(window, text=result)
d = Button(window, text="Done", command=done)
d.grid(column=0, row = 80)
window.mainloop()
答案 0 :(得分:2)
不幸的是,恐怕您 必须为每个复选框创建变量。
tkinter
具有特殊用途Variable Classes,用于保存不同类型的值,如果在创建variable=
之类的小部件时将一个实例指定为Checkbutton
选项,它会在用户更改值时自动设置或重置其值,因此您的程序要做的就是通过调用其get()
方法来检查其当前值。
下面是修改您的代码的示例,以在循环中创建它们(并在done()
回调函数中使用它们):
import random
from tkinter import *
window = Tk()
#window name and header
window.title("Custom Random SSBU")
lbl = Label(window, text="Select the fighters you would like to include:")
lbl.grid(column=1, row=0)
with open("Fighters.txt") as fighters:
ft = fighters.read().splitlines() # List of all the character names.
fv = [BooleanVar(value=False) for _ in ft] # List to track which boxes are checked.
ff = [] # List to place final character strings.
def reset():
for var in fv:
var.set(False)
rst = Button(window, text="Reset", command=reset)
rst.grid(column=0, row=3)
for i, (name, var) in enumerate(zip(ft, fv)):
chk_btn = Checkbutton(window, text=name, variable=var)
chk_btn.grid(column=0, row=i+4, sticky=W)
def done():
global ff
ff = [name for name, var in zip(ft, fv) if var.get()] # List of checked names.
# Randomly select one of them.
choice.configure(text=random.choice(ff) if ff else "None")
d = Button(window, text="Done", command=done)
d.grid(column=0, row=len(ft)+4)
choice = Label(window, text="None")
choice.grid(column=1, row=3)
window.mainloop()
我不确定您想将包含结果的Label
移到何处,所以我只是将其放在 Reset 按钮的右侧。
答案 1 :(得分:1)
variable = fv[y]
这会在创建Checkbutton时查找fv[y]
的值,即整数0
,并将其用于variable
参数。
您需要使用value-tracking classes provided by TKinter之一的实例。在这种情况下,我们需要BooleanVar
,因为我们正在跟踪布尔状态。我们仍然可以提前在列表中创建它们:
text = open("Fighters.txt").readlines()
# Let's not hard-code the number of lines - we'll find it out automatically,
# and just make one for each line.
trackers = [BooleanVar() for line in text]
# And we'll iterate over those pair-wise to make the buttons:
buttons = [
Checkbutton(window, text = line, variable = tracker)
for line, tracker in zip(text, trackers)
]
(但是我们不能不能做,例如trackers = [BooleanVar()] * len(text)
,因为这使我们对相同的跟踪器使用了78次,因此每个复选框都将共享该跟踪器;我们需要分别进行跟踪。)
当您单击复选框时,TKinter将自动更新对应的BooleanVar()
的内部状态,我们可以使用其.get()
方法进行检查。另外,当我们为random.choice
设置选项时,我们想为按钮而不是跟踪器选择相应的文本。我们可以再次使用zip
技巧来做到这一点。
所以我们想要更多类似的东西:
result_label = Label(window) # create it ahead of time
def done():
result_label.text = random.choice(
label
for label, tracker in zip(text, trackers)
if tracker.get()
)