Python,tkinter:无法使用 Pickle 保存

Python, tkinter: Can't save with Pickle

我不明白为什么我的代码不会 save/load 任何东西。

我希望用户能够在 GUI 中输入一个或多个任务,然后保存它们以便以后能够加载它们。我之前在另一个 GUI 中成功地完成了此操作,并且为此使用了相同的方法,但是它不起作用。 如果我按下加载它不会加载任何东西,而且保存过程中发生了什么我有点不清楚。

如果我 运行 程序,添加一个任务,保存它,然后删除它并按“加载任务”,它会显示类似 的内容<main.列表框中 0x0000018971142F10 处的任务对象>

如果我创建了一个任务,保存它,关闭程序,然后再次 运行 然后按“加载任务”没有任何反应。

代码:

import tkinter.messagebox
import pickle


task_list = []

class Task:
    def __init__(self, n):
        self.name = n

def show_tasks():
    task = task_list[-1]

def open_add_task():
    taskwin = Toplevel(root)
    taskwin.focus_force()
    
    #name
    titlelabel = Label(taskwin, text='Title task concisely:', font=('Roboto',11,'bold')).grid(column=1, row=0)
    name_entry = Entry(taskwin, width=40, justify='center')
    name_entry.grid(column=1, row=1)
    

        
    def add_task():
        if name_entry.get() != '': 
                
            task_list.append(Task(name_entry.get()))
            show_tasks()
            listbox_tasks.insert(tkinter.END, name_entry.get())
            name_entry.delete(0, tkinter.END)
            taskwin.destroy()
        else:
            tkinter.messagebox.showwarning(title='Whoops', message='You must enter a task')

        
    Add_button = Button(taskwin, text='Add', font=('Roboto',10), command=add_task).grid(column=1, row=2)

    
def delete_task():
    try:
        task_index = listbox_tasks.curselection()[0]
        listbox_tasks.delete(task_index)
    except:
        tkinter.messagebox.showwarning(title='Error', message='You must select a task to delete')

def save_tasks():
    tasks = listbox_tasks.get(0, listbox_tasks.size())
    pickle.dump(tasks, open('Todo.dat', 'wb'))


def load_tasks():
    try:
        tasks = pickle.load(open('Todo.dat', 'rb'))
        listbox_tasks.delete(0, tkinter.END)
        for task in task_list:
            listbox_tasks.insert(tkinter.END, task)
    except:
        tkinter.messagebox.showwarning(title='Error', message='You have no tasks')
    

root = Tk()

task_frame = Frame()
# UI
your_tasks_label = Label(root, text='THESE ARE YOUR TASKS:', font=('Roboto',10, 'bold'), justify='center')
your_tasks_label.pack()

listbox_tasks = tkinter.Listbox(root, height=10, width=50, font=('Roboto',10), justify='center') 
listbox_tasks.pack()




#BUTTONS
New_Task_Button = Button(root, text='New Task', width=42, command=open_add_task)
New_Task_Button.pack()

button_delete_task = Button(root, text='Delete task', width=42, command=delete_task)
button_delete_task.pack()


button_save_tasks = Button(root, text='Save tasks', width=42, command=save_tasks)
button_save_tasks.pack()

button_load_tasks = Button(root, text='Load tasks', width=42, command=load_tasks)
button_load_tasks.pack()

root.mainloop()

正如我在评论中提到的,问题是您试图从包含 Task class 对象的列表中读取。要访问任务的内容,您必须使用 object.name.

由于您使用 tasks 变量存储 pickle 文件的内容,因此您需要在 for 循环中使用相同的内容。

我还想通知您,当您从 pickle 文件加载时,在关闭应用程序后,您不会将其插入 task_list

我建议您创建一个单独的函数,仅用于将任务插入 ListBox 并将其保存为一个列表,并在您从 pickle 文件加载时调用该函数。


...
def open_add_task():
    taskwin = Toplevel(root)
    taskwin.focus_force()
    
    #name
    titlelabel = Label(taskwin, text='Title task concisely:', font=('Roboto',11,'bold')).grid(column=1, row=0)
    name_entry = Entry(taskwin, width=40, justify='center')
    name_entry.grid(column=1, row=1)
    

        
    def add_task():
        if name_entry.get() != '': 
            insertToList(name_entry.get())
            taskwin.destroy()
        else:
            tkinter.messagebox.showwarning(title='Whoops', message='You must enter a task')

        
    Add_button = Button(taskwin, text='Add', font=('Roboto',10), command=add_task).grid(column=1, row=2)


def insertToList(task):
    task_list.append(Task(task))
    show_tasks()
    listbox_tasks.insert(tkinter.END, task)

def load_tasks():
    global task_list
    try:
        with open('Todo.dat', 'rb') as f:
            tasks = pickle.load(f)
            
        listbox_tasks.delete(0, tkinter.END)
        task_list = []
        for task in tasks:
            insertToList(task)
        print(task_list, tasks)
    except:
        tkinter.messagebox.showwarning(title='Error', message='You have no tasks')

...