0

I'm writing a minimalist image tagging app that will list out all the image files in a specific location alongside a dropdown menu to select the options for tagging the image. Once the images are tagged, I need to save the changes to a JSON file and I've got a button for that. How can we read all the options selected so that it can be written into a file?

Following is the code so far:

from tkinter import N, RIGHT, Button, OptionMenu, Scrollbar, StringVar, Tk, Canvas, Frame, Label

class App:
    def __init__(self):
        self.root = Tk()
        self.tags = ['Apples', 'Oranges', 'Berries']
        self.GetRows()    
        self.SaveButton()
        self.root.mainloop()

    def GetRows(self):

        self.canvas = Canvas(self.root)
        self.scroll_y = Scrollbar(self.root, orient="vertical", command=self.canvas.yview)
        self.frame = Frame(self.canvas)
        
        lst = [f"A01{str(i)}.JPG" for i in range(100)]

        for idx, r in enumerate(lst):
            filename = Label(self.frame, text=r)
            filename.grid(row=idx+2, column=0, sticky=N)
            
            label = StringVar()
            drop = OptionMenu(self.frame, label, *self.tags)
            drop.grid(row=idx+2, column=1)
        
        # put the frame in the canvas
        self.canvas.create_window(0, 0, anchor='nw', window=self.frame)

        # make sure everything is displayed before configuring the scrollregion
        self.canvas.update_idletasks()

        self.canvas.configure(scrollregion=self.canvas.bbox('all'),
                 yscrollcommand=self.scroll_y.set)
        
        self.canvas.pack(fill='both', expand=True, side='left')
        self.scroll_y.pack(fill='y', side='right')


    def SaveState(self):
        pass

    def SaveButton(self):
        self.save_button = Button(self.root, text="Save Changes", padx=50, pady=10, command=self.SaveState)
        self.save_button.pack(side=RIGHT)
        


if __name__ == '__main__':
    App()

The SaveState method is what will be used to write the selections so far into a file.

Thanks in advance!

vivekveeramani
  • 144
  • 1
  • 12
  • You haven't stated what is the expected content in the JSON file. Also you should try to do it yourself first and post the issue you come across instead of asking for code. – acw1668 Mar 28 '22 at 02:07
  • Basically a key-value pair of the filenames and selected options. Derek's answer below works. – vivekveeramani Mar 29 '22 at 14:55

1 Answers1

1

In order to make OptionMenu results available try modifying your code so that all StringVars are accessible outside of GetRows.

    def GetRows(self):
        ...
        # Define label as a list
        self.label = []
        for idx, r in enumerate(lst):
            filename = Label(self.frame, text=r)
            filename.grid(row=idx+2, column=0, sticky=N)
            
            label = StringVar()
            drop = OptionMenu(self.frame, label, *self.tags)
            drop.grid(row=idx+2, column=1)
            # Save StringVar reference
            self.label.append(label)
        ...

    def SaveState(self):
        self.data = dict()
        # Retrieve results into dictionary
        for i, a in enumerate(self.label):
            self.data[f"A_{i}"] = a.get()
        print(self.data)

Then use json.dump(self.data, a_file) to save it

Derek
  • 1,916
  • 2
  • 5
  • 15