json 保存tkinter GUI的示例

qeeaahzv  于 2023-01-27  发布在  其他
关注(0)|答案(1)|浏览(142)

我正在开发一个带有“添加输入框”按钮的GUI,单击该按钮时会添加一个输入框。我还想添加一个“保存为下一个会话”按钮,单击该按钮时,用户下次打开GUI时会加载当前条目。问题是,有时需要输入5个字段,我怎样才能保存输入字段的数量和它们的值呢?我不想使用pickle库。

import customtkinter
import threading
import tkinter

class MyGui:

    def __init__(self, app):
        self.app = app
        self.entry_list = []

        self.entry_1 = customtkinter.CTkEntry(master=self.app, placeholder_text="entry")
        self.entry_1.pack(pady=10, padx=10)

        self.add_entry_button = customtkinter.CTkButton(master=self.app, text="Add entry",    command=self.add_entry)
        self.add_entry_button.pack(pady=10, padx=10)

        self.save_button = customtkinter.CTkButton(master=self.app, text="Save for next session",    command=self.save_instance)
        self.save_button.pack(pady=10, padx=10)

    def add_entry(self):
        self.entry_list.append(self.entry_1)
        self.entry_1 = customtkinter.CTkEntry(master=self.app, placeholder_text="entry")
        self.entry_1.pack(pady=10, padx=10)

    def save_instance(self):
        pass

app = customtkinter.CTk()
running = MyGui(app)
app.mainloop()

如您所见,我有这个self.entry_list,其中包含所有entry字段对象,但我不知道以后如何使用它来加载GUI示例。

kknvjkwl

kknvjkwl1#

你需要使用某种存储机制。你不想使用pickle,这是一种机制。你也可以使用一个平面文件或数据库。在这种情况下,因为你使用的是条目小部件,一个包含每个条目内容的平面文件就足够了。一个sqlite数据库可能会更好,但在这种特定的情况下,它可能会矫枉过正。
无论你选择什么,你都不能把tkinter对象保存到磁盘上,这一点很重要。tkinter的实现使得这一点基本上是不可能的。所以,你必须保存你可以从中恢复tkinter对象的数据,而不是保存对象本身。
在您的例子中,您将条目保存到列表self.entry_list中,因此写入文件可能只是迭代条目以获取值并将其写入文件(假设您希望保留这些值)
下面的示例为简洁起见硬编码了文件名,但在生产代码中不应硬编码它。

def save_instance(self):
    data = [entry.get() for entry in self.entry_list]
    with open("entries.txt", "w") as f:
        text = "\n".join(data)
        f.write(text)

恢复条目只是一个逆向的过程,首先,我们需要修改add_entry以获得默认值,而且,您的实现奇怪地使用了self.entry_1,这是不必要的,所以我删除了它。
下面的示例假设保存到文件的数据是条目小部件的默认值。如果是,则它是占位符文本的名称,您可以轻松地进行修改。

def add_entry(self, text=""):
    entry = customtkinter.CTkEntry(master=self.app, placeholder_text="entry")
    self.entry_list.append(entry)
    entry.pack(pady=10, padx=10)
    entry.insert("end", text)

接下来,创建一个阅读数据和创建条目的方法,需要注意的是readlines在每一行都包含换行符,我们将其去掉。

def restore_entries(self):
    with open("entries.txt", "r") as f:
        data = f.readlines()
        for line in data:
            self.add_entry(line.strip())

这绝对不是解决问题的唯一方法。如果你不想保存默认值(或者占位符文本?)你可以只存储你想要保留的条目数。或者,就像我前面提到的,你可以使用数据库。使用数据库你可以存储行数,然后只保存有文本的条目的文本。或者,代替平面文件,您可以将数据保存为结构化格式,例如JSON。

相关问题