Tkinter 在Python中,如何获取动态创建的条目小部件的值

Tkinter 在Python中,如何获取动态创建的条目小部件的值,tkinter,dynamic,widget,Tkinter,Dynamic,Widget,Python 3.8.0 我正在创建一个简单的GUI,用于从文件中读取/写入一组货币值。用户可以通过更新文件创建新货币,GUI相应地生成标签和条目小部件 然后,用户可以更新货币的值,然后程序将这些值写回文件以供下次使用 我在项目中有3个文件: main_ar.py-主循环 ar\u currency\u window.py-GUI框架的类 currency.py-货币和价值的列表 代码如下所列,运行良好。该窗口将生成并创建标签和条目小部件,并用相应的值填充输入框 货币作为字典保存,其键为3个字母

Python 3.8.0

我正在创建一个简单的GUI,用于从文件中读取/写入一组货币值。用户可以通过更新文件创建新货币,GUI相应地生成标签和条目小部件

然后,用户可以更新货币的值,然后程序将这些值写回文件以供下次使用

我在项目中有3个文件:
main_ar.py
-主循环
ar\u currency\u window.py
-GUI框架的类
currency.py
-货币和价值的列表

代码如下所列,运行良好。该窗口将生成并创建标签和条目小部件,并用相应的值填充输入框

货币作为字典保存,其键为3个字母的货币代码。我现在需要做的是将这些值读回字典,以便将它们保存到文件中

我努力想找到一种方法将条目文本链接到货币词典,但以它为基础,我想出了一个解决方案

我现在维护一个单独的字典,它使用一个基于0的序列作为键(相当于Entry小部件的行号),并将货币代码作为值。然后我循环遍历它,在原始字典中找到货币,然后根据需要比较这些值

我确实尝试将原始字典绑定到条目小部件,但我无法使其工作-它没有生成错误,只是什么也没做

所以,我的问题是:有没有一种方法可以将字典绑定到条目小部件,或者用一种稍微不复杂的方法来解决这个问题

主管道

from ar_currency_window import Currency


root = Currency()
root.grid()
root.mainloop()
print("finished")
ar_currency_window.py

import tkinter as tk
from tkinter import ttk

class Currency(tk.Tk):

    def close_window(self):
        self.destroy()

    def save_values(self):
        for entry in self.currencyList:
            findCurrency = self.currencyList[entry]
            oldValue = self.currencies[findCurrency]
            newValue = self.entries[entry].get()

            if oldValue != newValue:
                self.currencies[findCurrency] = newValue

        print(self.currencies)

    def readCurrencies(self):
        myfile = "currency.py"
        with open(myfile) as raw_data:
            for item in raw_data:
                if ':' in item:
                    key, value = item.split(':', 1)
                    self.currencies[key] = value.strip()
                else:
                    pass  # deal with bad lines of text here
        print(self.currencies)

    def writeCurrencies(self):
        myfile = "currency.py"
        with open(myfile, 'w') as f:
            for key, value in self.currencies.items():
                f.write('%s:%s\n' % (key, value))

    def __init__(self):
        super().__init__()

        # The Currencies and Entries strutures
        self.currencies = dict()
        self.currencyList = dict()
        self.entries=[]

        # Set the title and frame properties
        self.title("AR Currency Management")
        self.frame = ttk.Frame(self, padding=(10,10))

        # Gets the requested values of the height and width.
        windowWidth = self.winfo_reqwidth()
        windowHeight = self.winfo_reqheight()

        # Gets both half the screen width/height and window width/height
        positionRight = int(self.winfo_screenwidth() / 2 - windowWidth / 2)
        positionDown = int(self.winfo_screenheight() / 2 - windowHeight / 2)

        # Positions the window in the center of the page.
        self.geometry("+{}+{}".format(positionRight, positionDown))

        # Read in the currencies from the file
        self.readCurrencies()

        # Now create the labels and entry boxes in the frame
        # We use a list to keep track of the entries, so we can reference the entered values later
        r = 0 # row counter
        for k in self.currencies:
            c_label = ttk.Label(self.frame, text=k)
            c_input = ttk.Entry(self.frame, textvariable=self.currencies[k])
            c_input.insert(0,self.currencies[k])

            c_label.grid(column=0, row=r, sticky="W")
            c_input.grid(column=1, row=r, sticky="w")
            self.entries.append(c_input)
            self.currencyList[r]=k
            r += 1

        # Button to save the values
        btnSave = ttk.Button(self.frame, text="Save Currency Values",command=self.save_values)
        btnExit = ttk.Button(self.frame, text="Close",command=self.close_window)
        btnSave.grid(column=0,row=r+1,sticky="W")
        btnExit.grid(column=0, row=r+2, sticky="W")

        self.frame.grid()
currency.py

EUR:1.14
CAD:1.13
POL:2.13
NOK:8.23
USD:0.98
OLK:3.33
PLZ:101.54
非常感谢
Darren

好的,所以我通过使用列表解决了我的问题,并最终找到了StringVar

因此,更新了以下代码部分:

for k in self.currencies:
    c_label = ttk.Label(self.frame, text=k)
    c_input = ttk.Entry(self.frame, textvariable=self.currencies[k])
    c_input.insert(0,self.currencies[k])
为此:

for k in range(len(self.currencies)):
    c_label = ttk.Label(master, text=self.currencies[k]['Code'], width=5)
    c_label.grid(column=0, row=r, sticky="W")

self.Rates.append( StringVar() )
    self.Rates[k].trace("w", lambda name, index, mode, sv=k:         
        self.validate_rate_data(name, index, mode, self.Rates[sv]))
    t = ttk.Entry(master, width=10,textvariable=self.Rates[k])
    t.insert(0, self.currencies[k]['Rate'])
    t.grid(column=1, row=r, sticky="w", padx=(10, 10))
函数变量_rate_data的定义如下:

def validate_rate_data(self,name, index, mode, var):
    #Scan the Rates and ensure they are numeric
    try:
        f_number = float(var.get())
    except ValueError:
        print("ERROR")
费率列表定义为
self.Rates=[]

StringVar
trace方法用于在小部件中的值更改时调用
validate\u rate\u date
方法。然后调用
get()