如何将字典数据插入Tkinter的Entry组件矩阵
问题描述
需要创建一个带有预定义值的Entry组件矩阵,直接输入字符串或整数时组件能正常显示对应值,但引用字典中的值时,组件显示.!labelframe3.!entry这类内容,实现代码如下:
from tkinter import * from PIL import ImageTk, Image from tkinter import messagebox from tkinter import ttk root = Tk() root.title("Simulador de Proteção") root.iconbitmap("logo.ico") root.geometry("1200x800") root.configure(background='black') # FRAME DA CAIXA DE TESTE # gerar lista de sinais signals_list = ['IA', 'IB', 'IC'] initial_values = {'mag-pre':0, 'phi-pre':120, 'mag-fault':0, 'phi-fault':0, 'mag-pos':0, 'phi-pos':0} signals_entries = dict.fromkeys(signals_list, initial_values) signals_values = dict.fromkeys(signals_list, initial_values) columns_list = list(initial_values.keys()) # criar o frame frame_testbox = LabelFrame(root, text="Caixa de teste") frame_testbox.grid(row=1, column=1, columnspan=2, padx=10, pady=10) # mostrar nomes das linhas row_idx = 1 for signal in signals_list: label = Label(frame_testbox, text=signal) label.grid(row=row_idx, column=0) row_idx += 1 # mostrar nomes das colunas label = Label(frame_testbox, text="Sinal") label.grid(row=0, column=0) col_idx = 1 for col in columns_list: label = Label(frame_testbox, text=col) label.grid(row=0, column=col_idx) col_idx += 1 # criar campos de entrada row_idx = 0 for signal in signals_list: row_idx += 1 col_idx = 1 for col in columns_list: signals_entries[signal][col] = Entry( frame_testbox, width=15, bg="white", fg="black", borderwidth=5 ) signals_entries[signal][col].grid(row=row_idx, column=col_idx) signals_entries[signal][col].insert(0, signals_values[signal][col] ) col_idx += 1
问题原因
使用dict.fromkeys(signals_list, initial_values)创建字典时,所有键都会指向同一个initial_values字典对象。当你在循环中给signals_entries[signal][col]赋值Entry组件时,实际上是修改了这个共享的字典,导致signals_values里的对应值也被替换成了Entry对象。后续调用insert时,插入的是Entry对象的字符串表示(也就是.!labelframe3.!entry这类内容)。
解决方案
给每个信号创建独立的initial_values副本,用字典推导式代替dict.fromkeys:
修改以下两行代码:
signals_entries = {sig: initial_values.copy() for sig in signals_list} signals_values = {sig: initial_values.copy() for sig in signals_list}
修改后的完整代码:
from tkinter import * from PIL import ImageTk, Image from tkinter import messagebox from tkinter import ttk root = Tk() root.title("Simulador de Proteção") root.iconbitmap("logo.ico") root.geometry("1200x800") root.configure(background='black') # FRAME DA CAIXA DE TESTE # gerar lista de sinais signals_list = ['IA', 'IB', 'IC'] initial_values = {'mag-pre':0, 'phi-pre':120, 'mag-fault':0, 'phi-fault':0, 'mag-pos':0, 'phi-pos':0} # 用字典推导式创建独立的字典副本 signals_entries = {sig: initial_values.copy() for sig in signals_list} signals_values = {sig: initial_values.copy() for sig in signals_list} columns_list = list(initial_values.keys()) # criar o frame frame_testbox = LabelFrame(root, text="Caixa de teste") frame_testbox.grid(row=1, column=1, columnspan=2, padx=10, pady=10) # mostrar nomes das linhas row_idx = 1 for signal in signals_list: label = Label(frame_testbox, text=signal) label.grid(row=row_idx, column=0) row_idx += 1 # mostrar nomes das colunas label = Label(frame_testbox, text="Sinal") label.grid(row=0, column=0) col_idx = 1 for col in columns_list: label = Label(frame_testbox, text=col) label.grid(row=0, column=col_idx) col_idx += 1 # criar campos de entrada row_idx = 0 for signal in signals_list: row_idx += 1 col_idx = 1 for col in columns_list: signals_entries[signal][col] = Entry( frame_testbox, width=15, bg="white", fg="black", borderwidth=5 ) signals_entries[signal][col].grid(row=row_idx, column=col_idx) signals_entries[signal][col].insert(0, signals_values[signal][col] ) col_idx += 1 root.mainloop() # 添加这行以启动窗口事件循环
补充说明
initial_values.copy()会创建一个新的字典副本,确保每个信号对应的字典都是独立的,修改其中一个不会影响其他。- 原代码缺少
root.mainloop(),添加后才能正常显示窗口。
内容的提问来源于stack exchange,提问作者Gabriel Ribeiro
相关产品推荐
相关产品推荐

