Search code examples
pythontkinterloadingoptionmenu

Loading previous saved answers Tkinter OptionMenu


I need a help to solve this issue when loading data to tkinter option menu. I have read some answers over Stackoverflow and I believe I am very close, but I can't see where I am mistaking.

The app is a questionnaire with several pages (I added just 2 just to make easier to understand what the app is about) that saves the information on an excel file and now I am trying to load that information back if the user decides to save momentarily and continue later.

Edited part below:

So far, all my loaded information is being stored but the option menu is not refreshing with the data.

A full running code with the simple part of what I have developed is below:

import tkinter as tk, pandas as pd
from tkinter import ttk, messagebox

window = tk.Tk()

choices_y_n = ['-', 'Yes', 'No'] 
Questionlist = ["A. Is true?:", "B. Is True? :","C. Is True? :", "D. True? :"]
dash_entry_quality = [" - ", " - ", " - ", " - ", " - ", " - ", " - "]

def global_save(): 
    list_answers = list(map(lambda x: x.get(), var))
    a = ({"Q1": list_answers})    
    dfa = pd.DataFrame.from_dict(a, orient='index').transpose()
    writer = pd.ExcelWriter("save_data.xlsx", engine='xlsxwriter')
    dfa.to_excel(writer, sheet_name='Save Files')
    writer.save()
    messagebox.showinfo("Success!", "Progress successfully saved!")  

def load():
    global dash_entry
    file = pd.read_excel("save_data.xlsx")        
    dash_entry = file["Q1"]
    for r in range(len(Questionlist)): 
        var[r].set('')
        option_menu['menu'].delete(0, 'end')
        for c in dash_entry:
            option_menu['menu'].add_command(label = c, command = tk._setit(var[r], c))
    messagebox.showinfo("Success!", "information successfully loaded!")  

window.columnconfigure(0, minsize=100)
window.columnconfigure(1, minsize=150)
window.columnconfigure(2, minsize=50)     
tk.Frame.configure(window, background = "white")
ttk.Label(window, text="Group A Checklist", background = "white").grid(row=1, column=0, columnspan=3, pady = 10)
ttk.Label(window, text="Questions: ", background="white").grid(row=2, column=0,columnspan=2, padx=10, pady = 10, sticky="W")
global var, option_menu
var= [tk.StringVar(window) for i in range(len(Questionlist))]
for r in range(len(Questionlist)): 
    ttk.Label(window, text=Questionlist[r], background = "white").grid(row= r+3, column=0, columnspan=2, padx=10, pady = 10, sticky="W")
    option_menu = ttk.OptionMenu(window, var[r], *choices_y_n)
    option_menu.grid(row = r+3, column=2, padx=10, sticky="WE")
ttk.Button(window, text="Save values", command = global_save, width=18).grid(row=16, column=0, padx=10, pady=15, sticky="W")
ttk.Button(window, text="Load values", command = load, width=18).grid(row=17, column=0, padx=10, pady=15, sticky="W")

window.mainloop()

Solution

  • You're over complicating things. There's no need to rebuild the complete OptionMenu, you can simply update the variables that contain the current answer to the loaded answers:

    def load():
        file = pd.read_excel("save_data.xlsx")        
        dash_entry = file["Q1"]
        for r in range(len(Questionlist)): 
            var[r].set(dash_entry[r])
        messagebox.showinfo("Success!", "Information successfully loaded!")