将先前Tkinter会话中的条目值存储在循环中

时间:2012-02-27 21:09:42

标签: python tkinter tkinter-entry

我试图创建一个Tkinter GUI,将所有输入框值保存到文本文件中,然后从该文本文件中读回数据,并在下一个会话启动时默认显示它们。我们说我有一个包含以下数据的文本文件:

one
two
three

使用以下代码:

#!usr/bin/env python
from Tkinter import *

class Tracker(Tk):
    def __init__(self, var1, var2, var3):
        Tk.__init__(self)

        # Create label
        app_label = Label(self, text="Enter value")
        app_label.pack()

        self.entry1 = StringVar()
        self.entry1.set(var1)
        ent1 = Entry(self,textvariable=self.entry1)
        ent1.pack()
        self.entry2 = StringVar()
        self.entry2.set(var2)
        ent2 = Entry(self,textvariable=self.entry2)
        ent2.pack()
        self.entry3 = StringVar()
        self.entry3.set(var3)
        ent3 = Entry(self,textvariable=self.entry3)
        ent3.pack()

        # Track 'delete window' event
        self.protocol("WM_DELETE_WINDOW", self.handler)

    def handler(self):
        f = open("backup.txt", "w")
        f.write(self.entry1.get()+'\n'+self.entry2.get()+'\n'+self.entry3.get())
        f.close()
        self.destroy()

if __name__ == "__main__":

    t = open("backup.txt")
    var = t.readlines()
    Text1 = var[0]
    Text2 = var[1]
    Text3 = var[2]

    # Initialize GUI
    app = Tracker(Text1, Text2, Text3)  
    app.mainloop()

我得到以下方框:

entry

我的代码应该读取文本文件中的数据,并显示带有文本文件中预定义值的输入框。但它表现得很有趣。它没有正确保存数据

  1. 我希望这个GUI能够运行,这样当我在上面显示的输入框中编辑数据时,它会被保存(在关闭会话时)并在下次运行时自动显示。

    < / LI>
  2. 有没有办法在循环中执行此操作,以便我可以显示任意数量的输入框而无需对输入窗口小部件进行硬编码?

2 个答案:

答案 0 :(得分:0)

您可以在循环中轻松创建小部件。严格来说,除非您真的想要,否则不需要为每个小部件创建StringVar,因为您可以使用每个小部件对象上的方法来获取和设置小部件值。

例如:

import Tkinter as tk

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        button = tk.Button(text="Save", command=self.save)
        button.pack(side="top")
        self.widgets = []
        for line in ["one","two","three","four"]:
            widget = tk.Entry(self)
            widget.insert(0, line)
            widget.pack(side="top", fill="x")
            self.widgets.append(widget)

    def save(self):
        for widget in self.widgets:
            print widget.get()

if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()

答案 1 :(得分:0)

将每个命令添加到列表中。您可能需要将事件处理程序绑定到Entry小部件。

无论如何,至于在启动时做的事情,在构造函数的末尾,你可以做这样的事情(使用Python 3.4语法,因为这是我所熟悉的)。

from tkinter import *;
…
def __init__(self, etc.)
    self.commands=[];
    try:
        log=self.load_log();
        self.myTextWidget.replace("1.0", END, "\n".join(log)); #join here turns it into a string with list items separated by new lines.
    except IOError:
        self.save_log();
def load_log(self):
    #load and return the log file
def save_log(self):
    #save the log file; I recommend just pickling the list. Note: to save it, you'll want to load the list from the file and extend it with self.commands, and then save it again.
def on_entry(self, event):
    self.commands.append(the_entry.get());

关闭程序时调用save_log。

如果我是你,我只会在每次输入命令时保存日志,而不是在你关闭程序时保存日志(因为即使程序关闭不当也会起作用),但也许它会是在你的情况下性能问题。