自生成按钮不会在重新启动 GUI 时持续存在

Self-generating buttons not persisting upon restarting GUI

我有一个基于条目创建自生成按钮的程序,因为这些按钮没有存储在程序中的任何位置,它们会在 GUI 重新启动后消失。我需要这些按钮在 GUI 终止后继续存在,但每次调用提交函数时仍会自行生成。值得注意的是,完整程序中有一个数据库存储f_name。我不确定如何从我的数据库中为每个数据集提取 f_name,或者我是否可以创建一个函数来将这些按钮最初生成时写入程序。

from tkinter import *
root = Tk()
root.title('Button')
root.geometry('400x400')
#Entry & Label
f_name = Entry(root, width=30)
f_name.grid(row=0, column=1)
f_name_lbl = Label(root, text="First Name:")
f_name_lbl.grid(row=0, column=0)

#Retrieves f_name and generates a button at next highest row
def gen_button():
    auto_button = Button(button_frame, text=f_name.get())
    auto_button.pack(side="top")

submit_btn = Button(root, text="Submit:", command=gen_button)
submit_btn.grid(row=1, column=0, columnspan=2, ipadx=100)

button_frame = Frame(root)
button_frame.grid(row=2, column=0, columnspan=2, sticky="nsew")
#Credit to Bryan Oakley for the auto_button.pack and the button_frame

tkinter 或 python 中没有内置任何东西可以自动为您保存和恢复数据,但是保存和恢复数据的能力是几乎所有编程语言的基础 属性。您只需编写代码即可。

从现有数据创建按钮

让我们从一个可以接受一个或多个字符串并创建按钮的函数开始。您已经有了这样的函数,但需要为该函数提供字符串,而不是让它从小部件中获取字符串。

def add_buttons(*items):
    for item in items:
        auto_button = Button(button_frame, text=item)
        auto_button.pack(side="top")

这样,我们现在可以传入将转换为按钮的字符串列表。

add_buttons("button one", "button two")

从文件中读取按钮

接下来,我们需要能够从某种存储中读取字符串列表。存储方法与本答案无关;该函数只需要 return 一个字符串列表。在这种情况下,我们将只读取一个平面文件。这些字符串很容易来自数据库或基于 Web 的服务。

from pathlib import Path

def get_items(path):
    if path.exists():
        with open(path, "r") as f:
            data = f.read().strip().splitlines()
            return data
    return []

path = Path("buttons.txt")
items = get_items(path)

有了这两个函数,我们就有了一种读取字符串列表并将它们转换为一系列按钮的方法。只需几行额外的代码,我们就有了一个可以工作的程序:

from pathlib import Path
import tkinter as tk

def add_buttons(*items):
    for item in items:
        auto_button = tk.Button(button_frame, text=item)
        auto_button.pack(side="top")

def get_items(path):
    if path.exists():
        with open(path, "r") as f:
            data = f.read().strip().splitlines()
            return data
    return []

root = tk.Tk()
button_frame = tk.Frame(root)
button_frame.pack(fill="both", expand=True, padx=10, pady=10)

path = Path("buttons.txt")
items = get_items(path)
add_buttons(*items)

root.mainloop()

如果您手动编辑工作目录中的文件“buttons.txt”以包含一行或多行文本,则每行文本都会有一个按钮。例如,编辑文件以包含以下内容:

button one
button two
button three

当你运行你的程序时,你会得到这样的东西:

将按钮文本保存到文件

拼图的最后一块是能够将数据保存到文件中。它看起来很像创建按钮的函数,只是它需要接受项目列表并将它们写入文件。

def save_items(path, items):
    with open(path, "w") as f:
        f.write("\n".join(items))

从 Entry 小部件创建新按钮

在您的原始代码中,您希望能够通过单击另一个按钮并从条目小部件获取文本来创建按钮。您可以创建一个新函数,从条目中获取文本,然后使用其他函数创建按钮并保存文本。

def submit():
    global items

    # get the text and append it to our global list of button text
    text = entry.get()
    items.append(text)

    # create the button
    add_buttons(text)

    # save the list of items
    save_items(path, items)

综合起来

这是完整的程序。它缺少错误检查,可能不应该依赖全局变量,但重点是说明如何使用文件保存和恢复数据。

from pathlib import Path
import tkinter as tk

def add_buttons(*items):
    for item in items:
        auto_button = tk.Button(button_frame, text=item)
        auto_button.pack(side="top")

def get_items(path):
    if path.exists():
        with open(path, "r") as f:
            data = f.read().strip().splitlines()
            return data
    return []

def save_items(path, items):
    with open(path, "w") as f:
        f.write("\n".join(items))

def submit():
    global items

    # get the text and append it to our global list of button text
    text = entry.get()
    items.append(text)

    # create the button
    add_buttons(text)

    # save the list of items
    save_items(path, items)

root = tk.Tk()
button_frame = tk.Frame(root)
entry = tk.Entry(root)
submit = tk.Button(root, text="Submit", command=submit)

entry.pack(side="top")
submit.pack(side="top")
button_frame.pack(side="top", fill="both", expand=True)

# initialize our list of buttons from a file
path = Path("buttons.txt")
items = get_items(path)
add_buttons(*items)

root.mainloop()

总结

这不是解决问题的唯一方法,但它说明了创建函数以读取数据、保存数据和显示数据的一般模式。您可以按照自己认为合适的方式自由地重新实现这些功能。