1
\$\begingroup\$

I wrote a small program that generates a GUI for a grocery list (any list honestly). The GUI has the capacity to open a file, save a file, and save then exit the GUI from a file menu. The grocery items are added one at a time to a listbox using a popup window. The added items can be deleted as well. The functionality is pretty minimal, but I was hoping for some feedback regards to structure and common practice. Any advice would be appreciated!

import tkinter as tk
from tkinter.filedialog import asksaveasfilename,askopenfilename
class NewForm(tk.Toplevel):
    keys = ['Name','Price']
    def __init__(self):
        tk.Toplevel.__init__(self)

        self.resizable(False,False)
        self.title('Add item')

        self.grab_set()

        self.labels={}
        self.variables={}

        for key in NewForm.keys:
            self.labels[key] = ''
            self.variables[key] = tk.StringVar()

        for label in self.labels.keys():
            frm = tk.Frame(self,relief=tk.RAISED,bd = 2)
            frm.pack(side=tk.TOP,expand=tk.YES,fill=tk.X)
            tk.Label(frm,text=label).pack(side=tk.LEFT)
            ent = tk.Entry(frm,textvar = self.variables[label])
            ent.pack(side=tk.RIGHT)

        tk.Button(self,text='Submit',command=self.Submit).pack(side=tk.TOP)

        self.wait_window()
    def Submit(self):
        for variable_value in self.variables.values():
            if len(variable_value.get())==0:
                tk.messagebox.showinfo('Warning','The fields are incomplete!')
                return
        self.destroy()

class Main(tk.Frame):

    def __init__(self,parent = None):
        tk.Frame.__init__(self,parent,relief = tk.RIDGE,bd=4,
                          width = 400,height = 300)
        self.master.title('Grocery List')
        self.pack(expand=tk.YES,fill=tk.BOTH)
        parent.minsize(width = 300,height=200)
        parent.maxsize(width = 500,height =400)

        self.add_menu()
        self.add_info()

        self.add_buttons()


    def add_menu(self):
        self.menu = tk.Menu(self.master)
        self.master.config(menu=self.menu)

        file = tk.Menu(self.menu,tearoff=False)
        file.add_command(label='Open',command = self.file_open)
        file.add_command(label='Save',command = self.file_save)
        file.add_command(label='Save and Exit',command = self.file_save_exit)
        self.menu.add_cascade(label='File',menu = file)

    def add_info(self):
        info_frame = tk.Frame(self,relief=tk.SUNKEN,bd=2)
        info_frame.pack(side=tk.TOP,expand=tk.YES,fill=tk.BOTH)
        self.sbar = tk.Scrollbar(info_frame)
        self.lbox = tk.Listbox(info_frame,relief = tk.SUNKEN,selectmode='multiple')

        self.sbar.config(command = self.lbox.yview)
        self.lbox.config(yscrollcommand = self.sbar.set)

        self.sbar.pack(side=tk.RIGHT,fill=tk.Y)
        self.lbox.pack(side=tk.TOP,expand = tk.YES,fill=tk.BOTH)

    def add_buttons(self):
        frame = tk.Frame(self,relief = tk.RAISED,bd=2)
        frame.pack(side=tk.TOP,expand=tk.YES,fill=tk.BOTH)
        tk.Button(frame,text='Add grocery item',
                        command = self.add_item).pack(side=tk.LEFT,
                                                         expand=tk.YES)                                                          
        tk.Button(frame,text='Delete grocery item',
                  command = self.delete_item).pack(side=tk.LEFT,
                                                   expand=tk.YES)
    def add_item(self):
        self.popup = NewForm()
        self.update_list()

    def delete_item(self):
        idx_to_delete = self.lbox.curselection()
        for idx in idx_to_delete[::-1]:
            self.lbox.delete(idx)

    def update_list(self):
        self.lbox.insert(0,self.popup.variables['Name'].get()+', '+self.popup.variables['Price'].get()+'\n')

    def file_open(self):
        file = askopenfilename()
        with open(file,'r') as f:
            contents = f.readlines()
            for line in contents:
                self.lbox.insert(0,line)

    def file_save(self):
        filename = asksaveasfilename()
        if filename:
            with open(filename,'w') as f:
                for line in self.lbox.get(0,tk.END):
                    f.write(line)

    def file_save_exit(self):
        self.file_save()
        self.master.destroy()

Main(tk.Tk()).mainloop()

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.