【问题标题】:Create checkboxes with Tkinter and then get the value of selected box(es) into a list使用 Tkinter 创建复选框,然后将选定框的值放入列表中
【发布时间】:2020-07-03 04:24:48
【问题描述】:

我正在尝试从列表中创建复选框。 (biomelis_ = ['Arctic','Hill','Coast', 'Desert', 'Forest','Grassland', 'Mountain', 'Swamp', 'Underdark','Underwater', 'Urban' ])。

然后我想选中这些框并按“开始”。我试图让输出成为一个列表。例如,如果我选中“Arctic”、“Hill”和“Coast”,我的输出将是 ['Arctic', 'Hill', 'Coast']。我一直在阅读文档,但我正在努力解决这个问题。

这里是完整的代码:

from tkinter import *

biomelis_ = ['Arctic', 'Hill', 'Coast', 'Desert', 'Forest', 'Grassland', 'Mountain', 'Swamp', 'Underdark', 'Underwater',
             'Urban']

root = Tk()
var = StringVar()


# var.set(biomelis_ [0])

def sel():
    biome_lis_selection = var.get()
    print(biome_lis_selection)
    return [biome_lis_selection]


for item in range(len(biomelis_)):
    l = Checkbutton(root, text=biomelis_[item], variable=var)
    print("l = Checkbutton(root, text=" + str(biomelis_[item]) + ", variable=" + str(var))
    l.pack(anchor='w')


def go():  ### runs tkinter

    biomes_Checklist = sel()
    b.config(state=NORMAL)
    b.delete('1.0', END)
    b.insert(INSERT, sel())
    b.config(state=DISABLED)


## defines go button. This launches the def go() when the go button is pressed.
go_button = Button(root, text="Go!", width=10, command=go)
go_button.pack()
b = Text(root)
b.pack()

root.mainloop()


这是我正在努力解决的部分 - 获取所选项目。

l = Checkbutton(root, text=biomelis_[item], variable=var)

这将返回“l”而不是列表中的单个项目。此外,所有复选框都会同时选中和取消选中。

【问题讨论】:

  • 我认为它会在 l = Checkbutton(root, text=biomelis_[item], variable=biomelis_[item]) 行中定义。所以 variable=biomelis_[item] 但我猜这是错误的
  • “我以为...那个 variable=biomelis_[item]”:这是一个命名参数,而不是如何分配 @ 987654327@ 到 tkinter 小部件。阅读The Variable Classes 怎么做。
  • 谢谢。我创建了一个名为 var = StringVar() 的变量类。然后我使用var.get()。我还更改了行 l = Checkbutton(root, text=biomelis_[item], variable=var)。我已经编辑了上面的代码以反映这一点。但是,当我按下 go 时,返回的是 'l'。此外,所有框同时选中和取消选中(不能选中单个框)。
  • “所有复选框同时选中和取消选中”:您需要一个 variable=Checkbutton(...。考虑使用这种方法:correctly-extend-a-tkinter-widget-using-inheritance

标签: python tkinter


【解决方案1】:

在我的解决方案中,我将每个 Checkbutton 分配为单独的 BooleanVar 以分别保存每个小部件的当前状态(即“已选中”或“未选中”),并将每个 Checkbuttons 保存在名为chkbtns。这样便于在其他函数中引用它们。

from tkinter import *

root = Tk()

biomelist = ['Arctic', 'Hill', 'Coast', 'Desert', 'Forest', 'Grassland', 'Mountain',
             'Swamp', 'Underdark', 'Underwater', 'Urban']

chkbtns = []
for biome in biomelist:
    btnvar = BooleanVar(value=False)
    chkbtn = Checkbutton(root, text=biome, variable=btnvar)
    chkbtn.var = btnvar  # Save associated tkinter variable.
    chkbtn.pack(anchor='w')
    chkbtns.append(chkbtn)

def sel():
    selected = [btn.cget('text') for btn in chkbtns if btn.var.get()]
    print(f'selected: {selected}')
    return selected

def go():
    biomes_Checklist = sel()
    b.config(state=NORMAL)
    b.delete('1.0', END)
    b.insert(INSERT, biomes_Checklist)
    b.config(state=DISABLED)

# Defines Go button. This launches the go() function when the go button is pressed.
go_button = Button(root, text="Go!", width=10, command=go)
go_button.pack()
b = Text(root)
b.pack()

root.mainloop()

【讨论】:

  • 你不需要for in range...。可以直接遍历列表for _ in biomelis_
  • @Bryan:我知道,我这样做是为了与创建 Checkbuttons 的 for 循环保持一致(而且它似乎不值得“优化”)。
【解决方案2】:

您可以将onvalueoffvalue 分配给复选按钮。如果您将onvalue 设置为您要检索的值并将off 值设置为空字符串,则获取值变得非常简单。

我们要做的第一件事是丢弃使用exec 的代码块。这根本没有必要。我们将在创建复选按钮的同时创建变量,并将它们附加到列表中。

其次,我们将直接循环biomelis_,并将onvalue定义为与文本相同:

vars = []
for biome in biomelis_:
    var = tk.StringVar(value="")
    vars.append(var)
    cb = tk.Checkbutton(root, text=biome, onvalue=biome, offvalue="", variable=var)
    cb.pack(side="top", anchor="w")

这样,获取值只是遍历变量列表并保留非空字符串的值:

def sel()
    selected = []
    for var in vars:
        value = var.get()
        if value != "":
            selected.append(value)
    return selected

该循环被简化为以下单行,但如果您刚开始使用 python,则更难阅读:

def sel():
    return [var.get() for var in vars if var.get()]

【讨论】:

  • 我还有一个问题要问你。 vars 显示为全局变量,在这种情况下非常有用。在代码中的哪一点将其声明为全局变量?
  • @Brack 它没有被声明为全局的,它是全局的,因为它是在全局范围内创建的。如果您在另一个函数中运行此代码,则必须将其声明为全局。
【解决方案3】:

这可以解决你的问题,但我认为有更安全和更好的方法来做到这一点:

顺便说一句,也许你不知道如何使用variable.read some documents

from tkinter import *

biomelis_ = ['Arctic', 'Hill', 'Coast', 'Desert', 'Forest', 'Grassland', 'Mountain', 'Swamp', 'Underdark', 'Underwater',
             'Urban']

biomelis_variable = [] # a list to save all the variable

root = Tk()

for i in biomelis_:
    exec('''
{0} = IntVar()
biomelis_variable.append({0}) # use exec()
'''.format(i))

def sel():
    biome_lis_selection = []
    for i in range(len(biomelis_)):
        check = biomelis_variable[i].get()
        if check:
            biome_lis_selection.append(biomelis_[i])

        # biome_lis_selection = var
    return biome_lis_selection # the selected checkbutton name


for item in range(len(biomelis_)):
    l = Checkbutton(root, text=biomelis_[item], variable=biomelis_variable[item])
    l.pack(anchor='w')


def go():  ### runs tkinter

    biomes_Checklist = sel()
    b.config(state=NORMAL)
    b.delete('1.0', END)
    b.insert(INSERT, sel())
    b.config(state=DISABLED)


## defines go button. This launches the def go() when the go button is pressed.
go_button = Button(root, text="Go!", width=10, command=go)
go_button.pack()
b = Text(root)
b.pack()

root.mainloop()


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-29
    • 2015-01-18
    • 1970-01-01
    • 2021-07-01
    • 2014-03-21
    • 1970-01-01
    相关资源
    最近更新 更多