从 Python 中的复选框获取变量

Get Variables from Checkbox in Python

我尝试创建多个复选框并获取它们是否被选中的信息。为此,我尝试使用 tkinter。复选框的数量是可变的。到目前为止,我找到了一种使用以下代码创建复选框的方法。这样,创建了 10 个复选框,人们可以在其中勾选任何一个

class Example(tk.Frame):
    def __init__(self, root, *args, **kwargs):
        tk.Frame.__init__(self, root, *args, **kwargs)
        self.root = root

        self.vsb = tk.Scrollbar(self, orient="vertical")
        self.text = tk.Text(self, width=40, height=20, 
                            yscrollcommand=self.vsb.set)
        self.vsb.config(command=self.text.yview)
        self.vsb.pack(side="right", fill="y")
        self.text.pack(side="left", fill="both", expand=True)
        
        n=10
        for i in range(n):
            cb = tk.Checkbutton(self, text="Modul %s" % i)
            self.text.window_create("end", window=cb)
            self.text.insert("end", "\n")

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

但是,信息没有保存在任何变量中。如果我在 cb 中添加要转储的变量,代码将检查每个复选框。编辑后的代码部分如下(对不起,我无法突出显示添加):

class Example(tk.Frame):
    def __init__(self, root, *args, **kwargs):
        tk.Frame.__init__(self, root, *args, **kwargs)
        self.root = root

        self.vsb = tk.Scrollbar(self, orient="vertical")
        self.text = tk.Text(self, width=40, height=20, 
                            yscrollcommand=self.vsb.set)
        self.vsb.config(command=self.text.yview)
        self.vsb.pack(side="right", fill="y")
        self.text.pack(side="left", fill="both", expand=True)
        
        n=10
        var1 = IntVar()
        val =[]
        for i in range(n):
            cb = tk.Checkbutton(self, text="Modul %s" % i, variable=var1)
            self.text.window_create("end", window=cb)
            self.text.insert("end", "\n") # to force one checkbox per line
            val.append(var1.get())

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

你能帮我在代码中添加什么才能让用户获得选中的模块吗?例如,如果有人勾选模块 0、2 和 6

,我将在“val”变量中得到一个包含 [1, 0, 1, 0, 0, 0, 1, 0, 0, 0] 的列表

期待您的反馈。

您在找这样的东西吗?

import tkinter as tk

def done():
    result = []
    for var in variables:
        result.append(var.get())
    print(result)

root = tk.Tk()

variables = []
check_buttons = []
for i in range(10):
    var = tk.IntVar(root)
    check_button = tk.Checkbutton(root, text="Modul %i" % i, variable=var)
    check_button.pack()

    variables.append(var)
    check_buttons.append(check_button)

done_button = tk.Button(root, text="Done", command=done)
done_button.pack()

root.mainloop()

我在名为 variables 的列表中创建了 10 个变量,并将它们连接到每个 Checkbutton

这很简单,错误是您正在为所有复选按钮创建一个 IntVar,您应该为不同的按钮创建不同的 IntVar。然后我想添加的是,而不是 valIntVar 的值,让它成为 IntVar 本身,这样以后它可以被重用。这里我使用 bind 打印列表,您可以创建一个按钮并向其添加 command 选项。

self.val = [] # self.val if you want to access it outside __init__, or just val
for i in range(n):
    var1 = IntVar()
    cb = tk.Checkbutton(self, text="Modul %s" % i, variable=var1)
    self.text.window_create("end", window=cb)
    self.text.insert("end", "\n") # to force one checkbox per line
    self.val.append(var1)
self.text.bind('<Return>',lambda e:print([x.get() for x in self.val])) # Dummy function to just print a new list

什么是[x.get() for x in self.val]?这是简单的列表理解,这意味着:

temp = [] # Any empty list
for x in self.val:
    temp.append(x.get())

这是另一种方法(根据您的了解,其他答案可能更适合您):

from tkinter import Tk, Checkbutton, IntVar
from functools import partial


def func(n):
    print(f'Selected {n + 1}') if variables[n].get() == 1 else print(f'Deselected {n + 1}')


variables = []

root = Tk()

for i in range(10):
    variables.append(IntVar())
    Checkbutton(root, text=f'Option {i + 1}', variable=variables[i], command=partial(func, i)).pack()

root.mainloop()

(根据@CoolCloud 的建议,您可以将显示的命令替换为:command=lambda i=i: func(i),这应该也可以,而且您不必导入 functools)

然而,这是一个非常紧凑的设置。

解释:

首先是一个空列表,其中将存储所有复选框变量。

然后在范围 10 中,这意味着将创建 10 个复选框,我们执行以下操作:

  1. 首先,我们将一个变量附加到将分配给每个 Checkbutton 的列表中

  2. 然后它创建一个Checkbutton并通过使用索引将变量添加到它并立即打包它。

关于那个命令:

partial 基本上使得在其参数中给出的函数将始终使用该变量执行。更多相关信息 here

func()函数:

选择时打印选项的编号,否则在取消选择时打印选项的编号(添加正确的 'selected: no' 和 'deselected: no')。也可以写成:

if all_checkboxes[n][0].get() == 1:
    print(f'Selected {n + 1}')
else:
    print(f'Deselected {n + 1}')

希望这对您有所帮助,如果您有任何问题可以问他们。

Source for information about Checkbox and its attributes and arguments.