2012-02-27 54 views
0

我试图创建一个Tkinter GUI,将所有输入框值保存到文本文件中,然后从该文本文件中读回数据,并在下一个会话时默认显示它们开始。比方说,我有以下数据的文本文件:将来自先前Tkinter会话的条目值存储在一个循环中

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的功能,这样,当我在上面显示的输入框中编辑数据,它被保存(在会议结束时),下一次自动显示我运行它。

  2. 有没有办法在循环中做到这一点,以便我可以显示任意数量的输入框而无需对输入小部件进行硬编码?

回答

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() 
+0

非常感谢。无论如何,'StringVar()'声明的好处/用处是什么?我当时觉得有必要告诉Tkinter每次更新给定的小部件。 – prrao 2012-02-28 13:00:14

+0

@prrao:你可以添加痕迹到变量。这使得每当用户改变某个东西时都可以调用一个函数。它还使得通过简单地设置关联小部件的值来轻松更新小部件。这不是必需的,但在许多情况下它是有用的。 – 2012-02-28 13:37:49

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。

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