【问题标题】:How to fix tkinter TypeError: keys must be str, int, float, bool or None, not Button?如何修复 tkinter TypeError:键必须是 str、int、float、bool 或 None,而不是 Button?
【发布时间】:2020-07-16 17:48:02
【问题描述】:
import json 
from tkinter import *
import os

listai = json.load(open("listai.txt"))
listap = json.load(open("listap.txt"))
dict = {}



def dictAdd(item, value):
     global listai, listap
     print(item) #i did this so i could see where it was getting the error
     print(value)
     if item not in listai:
          dictcreator()
          d = open("dicionario.txt", "w")
          dict[item] = value
          d.write(json.dumps(dict))
          listai.append(item)
          try:
               listap.append(float(value))
          except ValueError:
               listap.append(int(value))
          i = open("listai.txt", "w").write(json.dumps(listai))
          p = open("listap.txt", "w").write(json.dumps(listap))

#dictAdd("cereja", 3.9)



def dictcreator():
     global listai, listap
     for x in range(len(listai)):
          dict[listai[x]] = listap[x]
     d = open("dicionario.txt", "w").write(json.dumps(dict))

#dictcreator()


def Add():
     addtop = Toplevel()
     addtopheight = 300
     addtopwidth = 300
     addentryname = StringVar()
     addentryprice = StringVar()
     xwpos = int(mainwindow.winfo_screenwidth()/2 - addtopwidth/2)
     ywpos = int(mainwindow.winfo_screenheight()/2 - addtopheight/2)
     addtop.geometry(f"{addtopwidth}x{addtopwidth}+{xwpos}+{ywpos}")
     addtop.resizable(height = 0, width = 0)
     addtop.config(bg="lightgrey")
     addmainlabel = Label(addtop, text="Adicionar alimento novo", font="arial, 19", fg="green", bg="lightgrey").grid(pady=10, padx=8, row=0, column=0, columnspan=2)
     addlabeln = Label(addtop, text="Alimento -->", bg="lightgrey", font="arial, 10").grid(row=1, column=0, padx=2, pady=8)
     addentryn = Entry(addtop, bg="lightgrey", textvariable = addentryname).grid(row=1, column=1, padx=2, pady=5)
     addlabelp = Label(addtop, text="Preço-->", bg="lightgrey", font="arial, 10").grid(row=2, column=0, padx=2, pady=8)
     addentryp = Entry(addtop, bg="lightgrey", textvariable = addentryprice).grid(row=2, column=1, padx=2, pady=5)
     addbutton = Button(addtop, text="Adicionar", font="arial, 10", fg="green", relief=GROOVE, bg="lightgrey", command = lambda: dictAdd(str(addentryname.get()), str(addentryprice.get())))
     addbutton.grid(pady= 20, padx=10, row=3, column=0, columnspan=2)
     addtop.mainloop()
def mainwindow():
     global mainwindow
     width = 700
     height = 400
     mainwindow = Tk()
     xwpos = int(mainwindow.winfo_screenwidth()/2 - width/2)
     ywpos = int(mainwindow.winfo_screenheight()/2 - height/2)
     mainwindow.geometry(f"{width}x{height}+{xwpos}+{ywpos}")
     mainwindow.config(bg="lightgrey")
     mainwindow.title("Lista de Compras")
     mainwindow.resizable(height = 0, width = 0)
 
     mainlabel = Label(mainwindow, text="Lista de Compras", fg="grey", width=18, bg="lightgrey", font="arial, 32", justify="right").grid(pady=15, padx = 10, row=0, column=0, columnspan = 4)
     Button(mainwindow, text="Add", fg="green", width=5, command=Add, relief=GROOVE).grid(padx= 20, pady=2, row=0, column=5)

     def edit():
          edittop = Toplevel()
          edittopheight = 200
          edittopwidth = 200
          xwpos = int(mainwindow.winfo_screenwidth()/2 - edittopwidth/2)
          ywpos = int(mainwindow.winfo_screenheight()/2 - edittopheight/2)
          edittop.geometry(f"{edittopwidth}x{edittopwidth}+{xwpos}+{ywpos}")
          Label(edittop, text="w").grid(row=0, column=0)
          edittop.mainloop
 
 
     for x in range(1, len(listai) + 1):
          listai[x-1] = Label(mainwindow, text=f"{listai[x-1]} --> {listap[x-1]}€", font="18", fg="black", bg="lightgrey", justify="left", width=15).grid(padx = 10, pady = 2, row=x, column=1)
          listai[x-1] = Entry(mainwindow, fg="black", bg="lightgrey", textvariable=f"{listai[x-1]}tv").grid(padx = 5, pady=2, row=x, column=2)
          listai[x-1] = Button(mainwindow, text="Edit", fg="purple", width=5, command=edit, relief=GROOVE).grid(padx= 20, pady=2, row=x, column=4)
          listai[x-1] = Button(mainwindow, text="Eliminate", fg="red", width=7, command=edit, relief=GROOVE).grid(padx= 20, pady=2, row=x, column=5)

          listai[x-1] = Button(mainwindow, text="Eliminate", fg="red", width=7, command=edit, relief=GROOVE)#.grid(padx= 20, pady=2, row=x, column=5)
          listai[x-1] = Button(mainwindow, text="Eliminate", fg="red", width=7, command=edit, relief=GROOVE)#.grid(padx= 20, pady=2, row=x, column=5)

      
     mainwindow.mainloop()

mainwindow()

我得到错误:

"TypeError: 键必须是 str、int、float、bool 或 None,而不是 Button",

当我按下名为“addbutton”的按钮时。如果需要这里是终端的更多输出:

laranja
5.7
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Asus\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1883, in __call__
return self.func(*args)
  File "c:/Users/Asus/PycharmProjects/lista de compras/lista de compras.py", line 57, in <lambda>
addbutton = Button(addtop, text="Adicionar", font="arial, 10", fg="green", relief=GROOVE, bg="lightgrey", command = lambda: dictAdd(str(addentryname.get()), str(addentryprice.get())))
  File "c:/Users/Asus/PycharmProjects/lista de compras/lista de compras.py", line 16, in dictAdd
dictcreator()
  File "c:/Users/Asus/PycharmProjects/lista de compras/lista de compras.py", line 36, in dictcreator
    d = open("dicionario.txt", "w").write(json.dumps(dict))
  File "C:\Users\Asus\AppData\Local\Programs\Python\Python38-32\lib\json\__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "C:\Users\Asus\AppData\Local\Programs\Python\Python38-32\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Users\Asus\AppData\Local\Programs\Python\Python38-32\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
TypeError: keys must be str, int, float, bool or None, not Button

我想知道是否有人可以告诉我如何解决此错误:D。 如果有人向我解释解决此错误的方法,我将不胜感激。

为了更好地理解代码,基本上这是一个添加/删除/添加购物车项目的程序,文件“listai.txt”是所有食品项目的数组/列表。 文件“listap.txt”是所有价格的数组/列表。 基本上我所做的是创建一个名为 dictcreator 的函数,该函数创建一个字典(称为“dicionario.txt”,这是字典,但在葡萄牙语中),例如,从 listai.txt 获取项目 1 和从 listap.txt 获取价格 1 和把它们放在一起。

外部文件:

listai: ["cereja","banana","pera","maca","pessego"]

列表:[“1.2”,“1.9”,“2.3”,“3.1”,“3.9”]

dicionario: {"cereja": 1.2, "banana": 1.9, "pera": 2.3, "maca": 3.1, "pessego": 3.9}

【问题讨论】:

  • 代码中的缩进显示已损坏。从addlabeln = Label(...) 开始,缩进不清楚。该代码是Add 的一部分还是应该在Add 之外运行。在您修复它之前,我们无法运行此代码。如果您的示例不依赖于外部文件,这也会有所帮助。请尝试编写代码来处理一些硬编码的数据。如果由于某种原因不能,则需要包含示例数据文件。
  • 感谢您对此的提醒,我什至没有注意到它被错误识别但它就在这里(stackoverflow),因为在我的代码上它没问题,但再次感谢您让我知道.顺便说一句,正如你所说,我刚刚添加了外部文件和更多解释,以便更好地理解我的代码。
  • 我们只能看到您在问题中发布的内容,我们无法看到您个人计算机上的代码。
  • 是的,我知道这一点。但是有了我现在添加的信息,你能理解为什么会出现这个错误吗?
  • 当我运行这段代码(添加缺失的部分后)它工作正常。如果我输入一个字符串和一个整数并单击按钮,我不会收到任何错误。

标签: python json tkinter typeerror


【解决方案1】:

在python中,字典键可以是任何可散列的对象,而在json中它只能是str, int, float, bool or None。如果需要(不应该这样做),请尝试使用 dillpickle 来保存 tkinter 对象。希望对您有所帮助!

【讨论】:

  • 问题是,在我为按钮“addbutton”实现 lambda 函数之前,它一切正常,没有任何错误。我是否错误地调用了 lambda 函数?还是以不好的方式使用它?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 2017-12-08
  • 1970-01-01
  • 2019-04-23
  • 2018-11-25
相关资源
最近更新 更多