Question

I'm trying to create a Tkinter GUI that saves all entry box values into a text file, then reads back data from this text file and display them by default when the next session is started. Let's say I have a text file with the following data:

one
two
three

Using the following code:

#!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()

I get the following box:

entry

My code is supposed to read in the data from the text file and display the entry boxes with pre-defined values from the text file. But it's acting funny. It doesn't save the data correctly

  1. I want this GUI to function so that when I edit the data in the entry boxes displayed above, it gets saved (on closing the session) and displayed automatically the next time I run it.

  2. Is there a way to do this in a loop so that I can display any number of entry boxes without having to hard-code the entry widgets?

Was it helpful?

Solution

You can easily create widgets in a loop. Strictly speaking you don't need to create the StringVars for each widget unless you really want to, because you can get and set the widget value using methods on each widget object.

For example:

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

OTHER TIPS

Add each command to a list. You'll likely need to bind an event handler to your Entry widget(s) for that.

Anyway, as for doing things at startup, at the end of your constructor, you can do something like this (using Python 3.4 syntax because that's what I'm familiar with).

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());

Call save_log when you close the program.

If I were you, I'd just save the log every time you enter a command instead of just when you're closing the program (as it would work even when the program closed inappropriately), but maybe it would be a performance issue in your case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top