Save and Load GUI-tkinter
Question: I want to save and load my GUI.

I have made a GUI and I want that when I click on the save button.

It should save the GUI in some blob of data and when I click on load button
then it will load the same GUI again.

My GUI has various text widgets, drop down Option Menu. I am new to python, so
someone can help me on this, please?

I have tried pickle module, too.


Answer: You can't do what you want to do without doing the work yourself. You'll need
to write a function that gathers all the data you need in order to restore the
GUI, and then you can save that to disk. Then, when the GUI starts up you can
read the data and reconfigure the widgets to contain this data.

Tkinter gives you pretty much everything you need in order to accomplish it,
but you have to do all the work yourself. Pickling the GUI won't work.

Here's a contrived example. Enter a few expressions in the window that pops
up. Notice that they are added to the combobox. When you exit, the current
expression, the saved expressions, and the current value are all saved. The
next time you start the GUI, these values will be restored.

    
    
    import Tkinter as tk
    import ttk
    import pickle
    
    FILENAME = "save.pickle"
    
    class Example(tk.Frame):
        def __init__(self, parent):
            self.create_widgets(parent)
            self.restore_state()
    
        def create_widgets(self, parent):
            tk.Frame.__init__(self, parent, borderwidth=9,relief="flat")
    
            self.previous_values = []
    
            l1 = tk.Label(self, text="Enter a mathematical expression:", anchor="w")
            l2 = tk.Label(self, text="Result:", anchor="w")
            self.expressionVar = tk.StringVar()
            self.expressionEntry = ttk.Combobox(self, textvariable=self.expressionVar, values=("No recent values",))
            self.resultLabel = tk.Label(self, borderwidth=2, relief="groove", width=1)
            self.goButton = tk.Button(self, text="Calculate!", command=self.calculate)
    
            l1.pack(side="top", fill="x")
            self.expressionEntry.pack(side="top", fill="x",padx = (12, 0))
            l2.pack(side="top", fill="x")
            self.resultLabel.pack(side="top", fill="x", padx = (12, 0), pady=4)
            self.goButton.pack(side="bottom", anchor="e", pady=4)
    
            self.expressionEntry.bind("<Return>", self.calculate)
    
            # this binding saves the state of the GUI, so it can be restored later
            root.wm_protocol("WM_DELETE_WINDOW", self.save_state)
    
        def calculate(self, event=None):
            expression = self.expressionVar.get()
            try:
                result = "%s = %s" % (expression, eval(expression))
                self.previous_values.append(expression)
                self.previous_values = self.previous_values[-8:]
                self.expressionVar.set("")
                self.expressionEntry.configure(values=self.previous_values)
    
            except:
                result = "invalid expression"
    
            self.resultLabel.configure(text=str(result))
    
        def save_state(self):
            try:
                data = {
                    "previous": self.previous_values,
                    "expression": self.expressionVar.get(),
                    "result": self.resultLabel.cget("text"),
                }
                with open(FILENAME, "w") as f:
                    pickle.dump(data, f)
    
            except Exception as e:
                print "error saving state:", str(e)
    
            root.destroy()
    
    
        def restore_state(self):
            try:
                with open(FILENAME, "r") as f:
                    data = pickle.load(f)
                self.previous_values = data["previous"]
                self.expressionEntry.configure(values=self.previous_values)
                self.expressionVar.set(data["expression"])
                self.resultLabel.configure(text=data["result"])
            except Exception as e:
                print "error loading saved state:", str(e)
    
    
    if __name__ == "__main__":
        root = tk.Tk()
        Example(root).pack(fill="both", expand=True)
        root.mainloop()
    

