我的代码:
# -*- coding: utf-8 -*-
"""
Created on Sun Jan 22 14:47:36 2017
@author: Jose Chong
"""
import json
import tkinter
master = tkinter.Tk()
master.title("To-Do List (with saving!)")
master.geometry("300x300")
masterFrame = tkinter.Frame(master)
masterFrame.pack(fill=tkinter.X)
checkboxArea = tkinter.Frame(masterFrame, height=26)
checkboxArea.pack(fill=tkinter.X)
inputStuff = tkinter.Frame(masterFrame)
checkboxList = []
with open('toDoListSaveFile.json') as infile:
checkboxList = json.load(infile)
for savedCheckbox in checkboxList:
n = savedCheckbox
def destroyCheckbox():
checkboxRow.destroy()
del checkboxList[checkboxList.index(str(savedCheckbox))]
checkboxRow = tkinter.Frame(checkboxArea)
checkboxRow.pack(fill=tkinter.X)
checkbox1 = tkinter.Checkbutton(checkboxRow, text = n)
checkbox1.pack(side=tkinter.LEFT)
deleteItem = tkinter.Button(checkboxRow, text = "x", command=destroyCheckbox, bg="red", fg="white", activebackground="white", activeforeground="red")
deleteItem.pack(side=tkinter.RIGHT)
def drawCheckbox():
newCheckboxInput = entry.get()
def destroyCheckbox():
checkboxRow.destroy()
del checkboxList[checkboxList.index(newCheckboxInput)]
checkboxList.append(newCheckboxInput)
entry.delete(0,tkinter.END)
checkboxRow = tkinter.Frame(checkboxArea)
checkboxRow.pack(fill=tkinter.X)
checkbox1 = tkinter.Checkbutton(checkboxRow, text = checkboxList[-1])
checkbox1.pack(side=tkinter.LEFT)
deleteItem = tkinter.Button(checkboxRow, text = "x", command=destroyCheckbox, bg="red", fg="white", activebackground="white", activeforeground="red")
deleteItem.pack(side=tkinter.RIGHT)
def createInputStuff():
paddingFrame = tkinter.Frame(inputStuff, height=5)
paddingFrame.pack(fill=tkinter.X)
buttonDone.pack()
inputStuff.pack()
buttonAdd.pack_forget()
master.bind('<Return>', lambda event: drawCheckbox())
def removeInputStuff():
inputStuff.pack_forget()
buttonAdd.pack()
buttonDone.pack_forget()
master.unbind('<Return>')
buttonDone = tkinter.Button(inputStuff, text = "Close Input", command=removeInputStuff)
buttonAdd = tkinter.Button(masterFrame, text="Add Item", command=createInputStuff)
buttonAdd.pack()
topInput = tkinter.Frame(inputStuff)
bottomInput = tkinter.Frame(inputStuff)
topInput.pack()
bottomInput.pack()
prompt = tkinter.Label(topInput, text="What do you want your checkbox to be for?")
prompt.pack()
entry = tkinter.Entry(bottomInput, bd=3)
entry.pack(side=tkinter.LEFT)
buttonConfirm = tkinter.Button(bottomInput, text="Confirm", command=drawCheckbox)
buttonConfirm.pack(side=tkinter.LEFT)
master.mainloop()
with open("toDoListSaveFile.json", 'w') as outfile:
json.dump(checkboxList, outfile)
我的代码的相关位是for savedCheckbox in checkboxList:
位(我认为),因此最好在那里阅读,这可能就是问题所在。
问题在于保存文件中加载的复选框,或者更确切地说是删除按钮。新复选框具有删除按钮,可以正常工作,但使用for savedCheckbox in checkboxList:
从保存文件加载的按钮具有出现故障的删除按钮。我的意思是:
它们全部删除最后加载的项目(来自保存文件)。因此,如果我的保存文件是四个复选框的列表[&#34; f&#34;,&#34; a&#34;,&#34; c&#34;,&#34; e&#34;],加载删除按钮会删除&#34; e&#34;。如果您点击&#34; c&#34;旁边的删除按钮,太糟糕了,您就会删除&#34; e&#34;。如果我在&#34; e&#34;之后尝试删除任何内容它消失了,它给了我错误&#34; ValueError:&#39; e&#39;不在列表中#34;。如果最后加载的复选框已被删除,他们也不会销毁checkboxRow,我不确定该复选框的副作用是否未被删除,或者我是否也搞砸了。
如何使删除按钮正常工作并正确删除复选框?正确删除是:
从JSON文件中删除了复选框的数据
复选框所在的整个复选框也应该被移除,选中复选框,复选框旁边的文本以及删除按钮。
对于&#34;适当的&#34;删除看起来像是看drawCheckbox()
,即工作删除框的位置。
答案 0 :(得分:0)
这是循环中定义的函数的常见问题。
def destroyCheckbox():
checkboxRow.destroy()
del checkboxList[checkboxList.index(str(savedCheckbox))]
destroyCheckbox
销毁checkboxRow
并从列表中移除savedCheckbox
,但在for循环结束时,checkboxRow
是最后一行,savedCheckbox
是最后一个复选框,所以所有按钮命令都做同样的事情:删除最后一项。
为了解决这个问题,我使用两个参数在for循环外定义了函数destroyCheckbox
:savedCheckbox和行。然后我使用lambda和default参数将命令传递给for循环内的按钮(参见How to understand closure in a lambda?)。
def destroyCheckbox(checkbox, row):
row.destroy()
checkboxList.remove(str(checkbox))
for savedCheckbox in checkboxList:
checkboxRow = tkinter.Frame(checkboxArea)
checkboxRow.pack(fill=tkinter.X)
checkbox1 = tkinter.Checkbutton(checkboxRow, text=savedCheckbox)
checkbox1.pack(side=tkinter.LEFT)
deleteItem = tkinter.Button(checkboxRow, text="x", bg="red", fg="white",
activebackground="white", activeforeground="red",
command=lambda c=savedCheckbox, r=checkboxRow: destroyCheckbox(c, r))
deleteItem.pack(side=tkinter.RIGHT)