如何在 Tkinter 中的 canvas 内的框架内获取所有 OptionMenu 小部件的值

How to get the values of all the OptionMenu widgets within a frame inside a canvas in Tkinter

我正在编写一个极简主义的图像标记应用程序,它会列出特定位置的所有图像文件,并在下拉菜单旁边列出 select 用于标记图像的选项。标记图像后,我需要将更改保存到 JSON 文件,我有一个按钮。我们如何读取所有选项 selected 以便将其写入文件?

以下是目前的代码:

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

到目前为止,SaveState 方法将用于将 select 离子写入文件。

提前致谢!

为了使 OptionMenu 结果可用,请尝试修改您的代码,以便 所有 StringVar 都可以在 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)

然后用json.dump(self.data,a_file)保存