我正在尝试使用python开发个人理财程序。我的费用分为几类,然后又分为子类。我使用嵌套字典来保存此数据,如下所示:
categorias_gastos = {'alimentacao_limpeza':{'almoco':0,
'supermercado':0},
'carro': {'combustivel':0,
'manutencao':0,
'multas_cnh':0},
'criaturas_estimacao': {'animais':0,
'plantas':0},
'despesas_medicas': {'consultas':0,
'dentista':0,
'exames':0,
'material_permanente':0,
'remedios':0 },
'formacao': 0,
'impostos': 0,
'lazer': 0,
'manutencao_casa':0,
'seguros':0,
'servicos':0,
'outros':0}
据我了解,花括号足以告诉python这是一个字典。然后,我尝试使用诸如categorias_gastos [key1] [key2]之类的嵌套索引访问特定数据。 key1和key2索引分别对应于费用类别和子类别中的密钥名称。这段代码是
key1 = StringVar()
key1.set('alimentacao_limpeza')
key2 = StringVar()
key1.set('supermercado')
这是麻烦开始的地方,因为python引发以下属性错误,
AttributeError: 'NoneType' object has no attribute '_root'
如果我改为进行以下更改
#key1 = StringVar()
#key1.set('alimentacao_limpeza')
key1 = 0
#key2 = StringVar()
#key1.set('supermercado')
key2 = 0
我可以让python运行我的代码。我尝试通过按钮中的函数回调来更新字典中的数据,
terminado_button = Button(somar_despesas_frame,
text="TERMINADO",
font=('arial', 10, 'bold'),
command=atualizar_categoria).grid(row=3,
column=0,
columnspan=4)
回调函数是
def atualizar_categoria():
global categorias_gastos, despesas, valores
total_despesas = sum(valores)
categorias_gastos[key1][key2] = total_despesas
print("CATEGORIA ATUALIZADA =",categorias_gastos[key1][key2])
然后引发另一个错误:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\ridim\Anaconda3\lib\tkinter\__init__.py", line 1699, in __call__
return self.func(*args)
File "<ipython-input-37-f7d458c1a385>", line 8, in atualizar_categoria
categorias_gastos[key1][key2] = total_despesas
TypeError: 'tuple' object does not support item assignment
如果我做了一些细微的改动,python然后将我的字典作为列表,并引发类似的错误。
有人可以告诉我我在做什么错吗?
完整代码如下:
# ------------------------------------------------------------------------------
# import classes, attributes, and methods of TKinter into current workspace
from tkinter import *
# ttk is Python's binding to the "themed widgets"
from tkinter import ttk
# ------------------------------------------------------------------------------
# global variables
categoria=0
categorias_gastos = {'alimentacao_limpeza':{'almoco':0,
'supermercado':0},
'carro': {'combustivel':0,
'manutencao':0,
'multas_cnh':0},
'criaturas_estimacao': {'animais':0,
'plantas':0},
'despesas_medicas': {'consultas':0,
'dentista':0,
'exames':0,
'material_permanente':0,
'remedios':0 },
'formacao': 0,
'impostos': 0,
'lazer': 0,
'manutencao_casa':0,
'seguros':0,
'servicos':0,
'outros':0}
contador = 0
despesa = 0
despesas = []
#key1 = StringVar()
#key1.set('alimentacao_limpeza')
key1 = 0
#key2 = StringVar()
#key1.set('supermercado')
key2 = 0
valores = []
global categoria, categorias_gastos, contador, despesa, despesas, key1, key2, valores
# ------------------------------------------------------------------------------
# define accountancy calculation functions
def atualizar_categoria():
global categorias_gastos, despesas, valores
total_despesas = sum(valores)
categorias_gastos[key1][key2] = total_despesas
print("CATEGORIA ATUALIZADA =",categorias_gastos[key1][key2])
def atualizar_despesas():
global contador,despesa, valores
valor_despesa = float(despesa.get())
contador = contador + 1
filename = ''.join(["Despesa_", str(contador)])
despesas.append(filename)
valores.append(valor_despesa)
print()
print("ATUALIZAR DESPESAS")
print(filename," = ",despesa.get())
def exibir_categoria():
print(categoria.get())
def imprimir_despesa():
global despesa, despesas, valores
print("Despesa =",despesa.get())
def selecionar_rubrica():
global despesa, despesas, key1, key2, valores
print()
print("SELECIONAR RUBRICA")
print("rubrica key1 =", key1)
print("rubrica key2 =", key2)
rubricas = ['Supermercado',
'Almoço']
selecionar_rubrica_frame = Toplevel(root)
var = StringVar()
var.set(rubricas[0])
# create title label
Label_1 = Label(selecionar_rubrica_frame,
text='SELECIONAR RUBRICA',
font=('arial', 12, 'bold')).pack()
for item in rubricas:
rubrica = Radiobutton(selecionar_rubrica_frame,
text=item,
font=('arial', 12, 'bold'),
indicatoron=0,
variable=var,
value=item,
command=somar_despesas)
rubrica.pack(anchor=W,
fill=X)
def somar_despesas():
global despesa, despesas, key1, key2, valores
print("key1 =", key1)
print("key2 =", key2)
despesa = StringVar()
despesa.set("Inserir valor da despesa")
# create frame
somar_despesas_frame=Toplevel(root)
# create title label
Label_1 = Label(somar_despesas_frame,
text='SOMAR DESPESAS',
font=('arial', 12, 'bold')).grid(row=0,
column=0,
columnspan=4)
#create operation label
despesa_label = Label(somar_despesas_frame,
text='Despesa',
font=('arial', 10, 'bold')).grid(row=1,column=0)
#add entry widget to my_frame_1
despesa_entry = Entry(somar_despesas_frame,
textvariable=despesa,
font=('arial', 10, 'normal')).grid(row=1,column=1)
validar_button = Button(somar_despesas_frame,
text="Validar",
font=('arial', 10, 'bold'),
command=atualizar_despesas).grid(row=1,column=3)
terminado_button = Button(somar_despesas_frame,
text="TERMINADO",
font=('arial', 10, 'bold'),
command=atualizar_categoria).grid(row=3,
column=0,
columnspan=4)
# ------------------------------------------------------------------------------
# Ia - create the toplevel or root window (an instance of tkinter.class)
root = Tk()
root.geometry('1400x700')
root.title('INSERIR GASTOS')
# ------------------------------------------------------------------------------
# CATEGORIAS_GASTOS_FRAME (EXPENDITURE CATEGORIES) AND ITS CONTENTS
# IIa - create categorias_gastos_frame
categorias_gastos_frame = Frame(root,
bd=2,
relief=SUNKEN)
categorias_gastos_frame.pack(side=LEFT,
anchor=N)
# add label to to my_frame_1
Label(categorias_gastos_frame,
text='SELECIONAR CATEGORIA DE GASTOS:',
font=('arial', 14, 'bold')).pack(anchor=W)
categorias_gastos = [("Alimentação / Limpeza",1),
("Carro",2),
("Criaturas de Estimação",3),
("Despesas Médicas",4),
("Formação",5),
("Impostos",6),
("Lazer",7),
("Manutenção da Casa",8),
("Seguros",9),
("Serviços",10),
("Outros",11)]
for text, category in categorias_gastos:
global categoria
botao = Radiobutton(categorias_gastos_frame,
text=text,
font=('arial', 12, 'bold'),
width=20,
padx=20,
indicator=0,
variable=key1,
value=categoria,
command=selecionar_rubrica)
botao.pack(anchor=W,
fill=X)
orientation = Label(categorias_gastos_frame)
orientation.pack(anchor=W,fill=X)
# Ib - the mainloop method is what keeps the root window visible
root.mainloop()
我知道使用全局变量不好,应该改用类。但这只是让我开始学习python。
非常感谢任何人都能为我提供的帮助。
答案 0 :(得分:0)
看起来像问题的一件事:您两次定义了全局categorias_gastos
。
第二个定义将覆盖第一个定义,它是元组列表而不是字典。为单选按钮元组使用其他名称,和/或将其隐藏(例如)“ make_radiobuttons”功能内。