【问题标题】:Get Variables from Checkbox in Python从 Python 中的复选框获取变量
【发布时间】:2021-04-09 21:10:43
【问题描述】:

我尝试创建多个复选框并获取它们是否被选中的信息。为此,我尝试使用 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] 的列表

期待您的反馈。

【问题讨论】:

    标签: python tkinter checkbox


    【解决方案1】:

    你在寻找这样的东西吗?

    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

    【讨论】:

    • 谢谢。需要在代码中添加mainloop
    • @Fadri 忘记了mainloop:D。我编辑了我的答案
    【解决方案2】:

    这很简单,错误是您为所有复选按钮创建了一个IntVar,您应该为不同的按钮创建不同的IntVar。然后我要补充的是,不是val 是来自IntVar 的值,而是让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())
    

    【讨论】:

      【解决方案3】:

      这是另一种做法(可能其他答案会更适合您,具体取决于您所知道的):

      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)

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

      解释:

      首先有一个空列表,所有 Checkbox 变量都将存储在其中。

      然后在范围 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}')
      

      希望这会有所帮助,如果您有任何问题,请咨询他们。

      Checkbox 及其属性和参数的信息来源。

      【讨论】:

      • 为什么你的“你”总是以大写开头?
      • @CoolCloud 因为它表示尊重,不是吗?(​​所以这是从道德的角度来看)而且我刚刚了解了 partial 是如何工作的,这让我能够进一步减少我的代码。
      • lambda i=i 做同样的事情 partial 在这里做,但没关系。不,它看起来不尊重,但如果你有这种感觉,那很好。
      • @CoolCloud 非常感谢您提供的信息,但不知道(关于 lambda)。关于“你”,我认为它是正式的,用来写一封正式信的那个,“你”的版本(因为在我的语言中也是如此)所以这就是我使用它的原因。而且感觉这仍然是与我不认识的人交谈的正确方式(即使我也在与朋友的日常聊天中使用它(我的语言中“你”的正式形式))
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-05
      • 1970-01-01
      • 2013-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多