简体   繁体   English

如何使用 Tkinter 正确制作 OPEN 和 SAVE 功能?

[英]How to properly make OPEN and SAVE function with Tkinter?

I am making a simple shopping list application.我正在制作一个简单的购物清单应用程序。 Whenever I try to save the content from the listbox shopping_list it saves as a tuple ('.., .., ...,') in the .txt file the function creates.每当我尝试从列表框shopping_list保存内容时,它都会在函数创建的.txt文件中保存为元组('.., .., ...,')

When I use the open button, the listbox displays the text as a tuple .当我使用open按钮时, listbox将文本显示为tuple

Example:例子:

If in the entry field I write something like pizza and add it to the listbox and save it.如果在输入字段中我写了一些类似pizza并将其添加到listbox并保存。 When I try to open the same file into the listbox , the listbox now displays: ('pizza') .当我尝试将同一个文件打开到listboxlistbox现在显示: ('pizza') How can I get the listbox to display only pizza ?如何让列表框只显示pizza

The code:编码:

from tkinter import *
from tkinter import messagebox
from tkinter import filedialog
from PIL import ImageTk, Image


def add_item():
    '''
        This function takes the input from the entry field
        and places the item in a shopping list.

    :return: Adds to list
    '''

    if len(user_input.get()) == 0: # Checks if user typed into the entry field.
        messagebox.showwarning("Warning", "No keys were detected from the Entry field") # Send warning for no input.

    # Else statement for adding the user input to shopping list.
    else:
        shopping_list.insert(END, user_input.get())
        user_input.delete(0, END)  # Deletes whatever the user wrote in the entry box after button is clicked.


def remove_item():
    '''
        This function deletes the selected items when REMOVE button is clicked
    '''
    try:
        selected = shopping_list.curselection()
        for item in selected[::-1]:  # Fetches all selected items from shopping list
            shopping_list.delete(item)


    # Make a warning if the shopping list is empty or items are not selected when REMOVE button is clicked.
    except TclError:
        messagebox.showwarning("Warning", "The shopping list is either empty \nor you didn't select an item")


def open_list():
    '''
        This function opens an existing shopping list that was previously saved.
    :return: Opens older saved files.
    '''
    root.file = filedialog.askopenfilename(initialdir="./", title="Select a file",
                                           filetypes=(("Txt files", "*.txt"), ("All files", "*,*")))

    with open(root.file, "r") as file:
        data_content = file.read()
        shopping_list.delete(0, END)
        shopping_list.insert(END, data_content)


def save_file():
    '''
        This function saves the whole shopping list and writes the content to the "shopping_list.txt" file.
    :return: None
    '''
    text_file = filedialog.asksaveasfilename(defaultextension=".txt")
    try:
        with open(text_file, "w") as file:
            file.write(str(shopping_list.get(0, END)))
    except FileNotFoundError:
        messagebox.showinfo("Alert", "No file was saved")

# backup eldre løsning:
"""
def save_file():
    '''
        This function saves the whole shopping list and writes the content to the "shopping_list.txt" file.
    :return: None
    '''
    root.filename = filedialog.asksaveasfilename()
    with open("shopping_list.txt", "w") as f:
        for i in shopping_list.get(0, END):
            f.write(i+"\n")

"""



# Root files
root = Tk()
root.title("Skoleoppgave OBLIG 5")
root.iconbitmap('favicon.icns')
root.geometry("500x500")
root.resizable(0, 0)


# TODO: Entry  widget  ENTRY  1
# Creating an Entry widget so user can add items to shopping-list.
user_input = Entry(root, relief=SUNKEN)
user_input.pack()
user_input.place(x=250, y=20, anchor=N)


# Todo: Buttons widget ADD ITEM 2
# Make a Button-widget that adds the user input from entry field to the shopping list.
add_entry = Button(root, text="ADD ITEM", command=add_item, padx=10, pady=5)
add_entry.pack()
add_entry.place(x=158, y=57)



# Todo: Listbox  widget 4
# Creating Listbox for shopping list items
shopping_list = Listbox(root, selectmode=EXTENDED)
shopping_list.pack()
shopping_list.place(x=160, y=100)

"""
# Opens last saved shopping list when program starts.
try:
    read = open("shopping_list.txt","r")
    list_file = read.readlines()
    read.close()
    for data in list_file:
        shopping_list.insert(0, END, data)
except FileNotFoundError:
    read = open("shopping_list.txt","w")
"""


# Todo: Buttons widget REMOVE 3
# Make a Button-widget that deletes the selected item from shopping list
remove_entry = Button(root, text="REMOVE", command=remove_item, padx=10, pady=5)
remove_entry.pack()
remove_entry.place(x=160, y=285)


# Todo: Buttons widget OPEN 5
# Make a Button-widget that deletes the selected item from shopping list
open_file = Button(root, text="OPEN", command=open_list, padx=10, pady=5)
open_file.pack()
open_file.place(x=160, y=285)

# Todo: Buttons widget SAVE 6
# Make a Button-widget that deletes the selected item from shopping list
save_file = Button(root, text="SAVE", command=save_file, padx=10, pady=5)
save_file.pack()
save_file.place(x=282, y=57)

root.mainloop()

As mentioned in the comments, you are trying to put a string into a method that is asking for a tuple, that will give an error.正如评论中提到的,您试图将一个字符串放入一个要求元组的方法中,这会产生错误。

so one way is that you add functionality both in reading and writing to write a data format to the file that you control yourself.因此,一种方法是在读取和写入方面添加功能,以将数据格式写入您自己控制的文件中。 tip is trying to replicate one to one what you see in the listbox to the textfile.提示正在尝试将您在列表框中看到的内容一对一复制到文本文件中。 It looks like your "eldre losning" will put one item per line.看起来你的“eldre losning”会每行放一个项目。 So the thing is to read the file so that you get a list of strings where every row becomes an item in the list.所以事情是读取文件,以便您获得一个字符串列表,其中每一行都成为列表中的一个项目。 Hint... .split on strings works good for that.提示... .split对字符串很有用。

Or, just deal with the string you already have in the file.或者,只需处理文件中已有的字符串。 One way to do that is to add/modify the following.一种方法是添加/修改以下内容。

from ast import literal_eval # added import for safe evals

# modified open
with open(root.file, "rt") as file:
    data_content = literal_eval(file.read())
    shopping_list.delete(0, END)
    shopping_list.insert(END, *data_content)

Side note #1, you don't need .pack() if you use .place .旁注#1,如果您使用.place则不需要.pack() Side note #2, next time around, mention that you are doing homework upfront.旁注#2,下次,提到你正在做功课。 Side note #3, if you use what's in this answer - you might have to do some reading before you can explain why it could be done like this to be believed that you came up with it yourself :-)旁注#3,如果您使用此答案中的内容-您可能需要先阅读一些内容,然后才能解释为什么可以这样做以相信是您自己提出的:-)

Good luck with your studies and learning.祝你学习和学习顺利。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM