Python 删除按钮I';对于待办事项列表中的项目,我们仅删除最后一项,而不是其分配的项目

Python 删除按钮I';对于待办事项列表中的项目,我们仅删除最后一项,而不是其分配的项目,python,json,python-3.x,tkinter,Python,Json,Python 3.x,Tkinter,我的代码: # -*- 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)

我的代码:

# -*- 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)
#-*-编码:utf-8-*-
"""
创建于2017年1月22日星期日14:47:36
@作者:何塞·庄
"""
导入json
进口tkinter
master=tkinter.Tk()
master.title(“待办事项列表(带保存!)”)
几何硕士(“300x300”)
主框架=tkinter.Frame(主框架)
masterFrame.pack(填充=tkinter.X)
checkboxArea=tkinter.Frame(主框架,高度=26)
checkboxArea.pack(填充=tkinter.X)
inputStuff=tkinter.Frame(主框架)
复选框列表=[]
以open('toDoListSaveFile.json')作为内嵌:
checkboxList=json.load(infle)
对于复选框列表中的savedCheckbox:
n=savedCheckbox
def destroucheckbox():
checkboxRow.destroy()
del checkboxList[checkboxList.index(str(savedCheckbox))]
checkboxRow=tkinter.Frame(checkboxArea)
checkboxRow.pack(fill=tkinter.X)
checkbox1=tkinter.Checkbutton(checkboxRow,text=n)
复选框1.包装(侧面=左侧)
deleteItem=tkinter.Button(checkboxRow,text=“x”,command=destroyCheckbox,bg=“红色”,fg=“白色”,activebackground=“白色”,activeforeground=“红色”)
deleteItem.pack(侧=tkinter.RIGHT)
def drawCheckbox():
newCheckboxInput=entry.get()
def destroucheckbox():
checkboxRow.destroy()
del checkboxList[checkboxList.index(newCheckboxInput)]
附加(newCheckboxInput)
entry.delete(0,tkinter.END)
checkboxRow=tkinter.Frame(checkboxArea)
checkboxRow.pack(fill=tkinter.X)
checkbox1=tkinter.Checkbutton(checkboxRow,text=checkboxList[-1])
复选框1.包装(侧面=左侧)
deleteItem=tkinter.Button(checkboxRow,text=“x”,command=destroyCheckbox,bg=“红色”,fg=“白色”,activebackground=“白色”,activeforeground=“红色”)
deleteItem.pack(侧=tkinter.RIGHT)
def createInputStuff():
paddingFrame=tkinter.Frame(inputStuff,高度=5)
paddingFrame.pack(fill=tkinter.X)
buttonDone.pack()
inputStuff.pack()
按钮D.打包忘记()
master.bind(“”,lambda事件:drawCheckbox())
def removeInputStuff():
inputStuff.pack_-forget()
按钮和包装()
buttonDone.pack_忘记()
主控解除绑定(“”)
buttonone=tkinter.Button(inputStuff,text=“Close Input”,command=removeInputStuff)
buttonAdd=tkinter.Button(主框架,text=“添加项”,命令=createInputStuff)
按钮和包装()
topInput=tkinter.Frame(inputStuff)
bottomInput=tkinter.Frame(inputStuff)
topInput.pack()
bottomInput.pack()
prompt=tkinter.Label(topInput,text=“您希望您的复选框用于什么?”)
prompt.pack()
entry=tkinter.entry(底部输入,bd=3)
入口包装(侧面=左侧)
buttonConfirm=tkinter.Button(底部输入,text=“确认”,command=drawCheckbox)
按钮固定。包装(侧面=左侧)
master.mainloop()
以open(“toDoListSaveFile.json”,“w”)作为输出文件:
dump(复选框列表,输出文件)
我的代码的相关部分是checkboxList中savedCheckbox的
部分(我认为),因此最好通读一下,这可能就是问题所在

问题在于从保存文件加载的复选框,或者更确切地说是它们的删除按钮。新复选框中的删除按钮工作正常,但使用复选框列表中的savedCheckbox:从保存文件加载的复选框中的删除按钮出现故障。我的意思是:

它们都会删除最后加载的项目(从保存文件中)。因此,如果我的保存文件是由四个复选框组成的列表[“f”、“a”、“c”、“e”],则每个加载的删除按钮都会删除“e”。如果您单击“c”旁边的“删除”按钮,太糟糕了,您正在删除“e”。如果我试图在“e”消失后删除任何内容,它会给出错误“ValueError:“e”不在列表中”。如果上次加载的复选框已被删除,它们也不会销毁checkboxRow,我不确定这是复选框未被删除的副作用,还是我也弄糟了

如何使删除按钮正常工作并正确删除复选框?适当的删除是:

从JSON文件中删除复选框的数据

复选框所在的整个复选框行也应删除,选中复选框、复选框旁边的文本,并使用“删除”按钮


有关“正确”删除的外观,请查看
drawCheckbox()
,这是创建工作删除框的地方。

这是循环内部定义的函数的常见问题

def destroyCheckbox():
        checkboxRow.destroy()
        del checkboxList[checkboxList.index(str(savedCheckbox))]
destroyCheckbox
销毁
checkboxRow
并从列表中删除
savedCheckbox
,但在for循环的末尾,
checkboxRow
是最后一行,
savedCheckbox
是最后一个复选框,因此所有按钮命令都执行相同的操作:删除最后一项

为了解决这个问题,我使用两个参数在for循环外部定义了函数
destroyCheckbox
:savedCheckbox和row。然后,我使用lambda和默认参数将命令传递给for循环中的按钮(请参阅)


这是循环内部定义的函数的常见问题

def destroyCheckbox():
        checkboxRow.destroy()
        del checkboxList[checkboxList.index(str(savedCheckbox))]
destroyCheckbox
销毁
checkboxRow
并从列表中删除
savedCheckbox
,但在for循环的末尾,
checkboxRow
是最后一行,
savedCheckbox
是最后一个复选框,因此所有按钮命令都执行相同的操作:删除最后一项

为了解决这个问题,我使用两个参数在for循环外部定义了函数
destroyCheckbox
:savedCheckbox和row。然后,我使用lambda和默认参数将命令传递给for循环中的按钮(请参阅)


谢谢你的解决方案,它成功了!我不明白destroyCheckbox()如何知道“checkbox”指的是加载的复选框文本,“row”指的是checkboxRow。你能解释一下吗?事实上我想你在lambda中分配了这些。谢谢你的帮助!精确,我将复选框和行指定给