【问题标题】:NoneType error when trying to access tkinter checkbuttons from nested dict尝试从嵌套字典访问 tkinter 检查按钮时出现 NoneType 错误
【发布时间】:2019-12-12 09:16:52
【问题描述】:

我使用 for 循环在 tkinter 应用程序中创建了一组 (6) checkbuttons。到目前为止,我刚刚创建并布置了它们,但什么也没做。我希望他们做的是告诉另一个函数如何工作,具体取决于单击了哪个 checkbutton,但是当我尝试访问 checkbuttons 时,我收到了问题底部发布的错误。

我尝试将所有按钮制作为单独的代码行,但显然这是很多重复的代码,所以我使用 for 循环制作它们并将它们存储在嵌套的 dict 中,如下所示:

for i in self.atts:
    self.att_buttons[i] = {}
    self.att_buttons[i]["checkbutton"] = tk.Checkbutton(
        self.check_frame, text=i, font=("Courier", 15),
        onvalue = 1, offvalue = 0,
    ).pack(side=tk.LEFT)

我不确定这是否正确,但我是新手,我正在尽力而为。

我有一个roll() 函数,我想要的是检查按钮来修改该函数的结果,所以我尝试的是

def roll(self):
    """Roll dice, add modifer and print a formatted result to the UI"""
    value = random.randint(1, 6)
    if self.att_buttons["Str"]["checkbutton"].get() == 1:
        result = self.character.attributes["Strength"]["checkbutton].get()
        self.label_var.set(f"result: {value} + {result} ")
File "main_page.py", line 149, in roll
    if self.att_buttons["Str"]["checkbutton"].get() == 1: 
AttributeError: 'NoneType' object has no attribute 'get'

现在我假设这是因为我错误地调用了嵌套的 dict,但我尝试移动我的代码并尝试不同的点点滴滴,但我一直收到同样的错误。

更新

根据下面雨果的回答,我将 for 循环编辑为

for i in self.atts:
    self.att_buttons[i] = {}
    self.att_buttons[i]["checkbutton"] = tk.Checkbutton(
        self.check_frame, text=i, font=("Courier", 15),
        variable = tk.BooleanVar()#this is the change 
    )
    self.att_buttons[i]["checkbutton"].pack(side=tk.LEFT)`

如何调用 variable 来获取 roll() 函数中的特定检查按钮?

【问题讨论】:

  • pack() 方法返回 None,并且您将该值分配给 self.att_buttons[i]["checkbutton"]
  • 谢谢,我已经编辑了循环以分别打包每个按钮。

标签: python tkinter


【解决方案1】:

self.att_buttons["Str"]["checkbutton"] 返回 None,这就是 Python 抱怨你试图在其上调用 get() 的原因。

你写道:

for i in self.atts:
    self.att_buttons[i]["checkbutton"] = ...`

检查这是否真的发生在有错误的行之前,并检查self.atts 是否包含"Str"


另外,我认为这不是获取复选框状态的正确方法——请参阅Getting Tkinter Check Box State

回应您的编辑:

您添加了一个 BooleanVar,但您需要保留对它的引用,因为这是您访问实际值的方式:

# Make a dict associating each att with a new BooleanVar
self.att_values = {att: tk.BooleanVar() for att in self.atts}

for i in self.atts:
    self.att_buttons[i] = {}
    self.att_buttons[i]["checkbutton"] = tk.Checkbutton(
        self.check_frame, text=i, font=("Courier", 15),
        variable = self.att_values[i] 
    )
    self.att_buttons[i]["checkbutton"].pack(side=tk.LEFT)`

这是一个示例,您可以这样做,您只需要保留对 BooleanVar 的引用以便以后访问它们:

if self.att_values["Str"].get() == 1:

【讨论】:

  • 好的,谢谢一百万,我已将每个按钮设置为具有tk.BooleanVar() 的变量,我是否必须在 for 循环之外定义这些变量,然后以这种方式调用状态,或者我可以在 for 循环中定义变量,如果是,我将如何在 roll 函数中调用它们?
  • 将变量与 CheckButton 关联的部分在哪里?我认为它应该在 tk.Checkbutton(...) 但我看不到它。
  • 我刚刚将它添加到更新中的主代码 ave 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-14
  • 1970-01-01
  • 2017-02-14
  • 2012-05-02
相关资源
最近更新 更多