如何在Tkinter新窗口中基于StringVar更新绑定Entry的StringVar
问题描述
在Tkinter开发场景中,主窗口包含多个生成SQL脚本的按钮,点击按钮会弹出新窗口,新窗口内有三个分别绑定database、table、column这三个StringVar的Entry控件。当在绑定table的Entry2中输入正确的表名时,show_columns函数会查询数据库(假设库名为DATABASE)并获取该表的列名,将列名拼接为字符串后打印。现在需要将该列名字符串赋值给绑定Entry3的column变量,如何实现?
解决方案
要实现需求,需对现有代码做以下核心修改:
- 让
show_columns函数返回列名字符串:在成功查询后返回拼接好的列名字符串,异常场景返回空字符串,方便后续赋值。 - 在trace回调中传递
column变量并赋值:调整table.trace_add的回调逻辑,将column变量传入,调用show_columns后用column.set()方法同步值到Entry3。 - 优化字符串拼接逻辑:用
join方法替代循环拼接,更高效且避免末尾多余逗号(若需保留末尾逗号可自行调整)。
修改后的完整代码
def show_columns(table): query = f"select * from [DATABASE].[dbo].[{table}] where 1=0" cursor = conn.cursor() try: cursor.execute(query) column_names = [column[0] for column in cursor.description] # 用join优化拼接,自动避免末尾多余逗号 columns_str = ",".join([f"[{col}]" for col in column_names]) print(columns_str) return columns_str except Exception as e: print(f'Error: {e}') return "" def open_window(text, button): # Create a new window new_window = Toplevel() # Set the window title and size new_window.title(text) new_window.geometry("600x460") new_window.config(bg="light gray") new_window.resizable(False, False) database = StringVar() table = StringVar() column = StringVar() # Create some text fields label1 = Label(new_window, text="Database name:").grid(row=0, column=0, pady=5) entry1 = Entry(new_window, textvariable=database).grid(row=0, column=1, padx=5, pady=5) label2 = Label(new_window, text="Table name:").grid(row=1, column=0, pady=5) entry2 = Entry(new_window, textvariable=table).grid(row=1, column=1, padx=5, pady=5) label3 = Label(new_window, text="Column name:").grid(row=2, column=0, pady=5) entry3 = Entry(new_window, textvariable=column).grid(row=2, column=1, padx=5, pady=5) # 修改trace回调,传入column变量并赋值 table.trace_add('write', lambda name, index, mode, sv=table, col_var=column: col_var.set(show_columns(sv.get()))) window = Tk() # code for connecting to database # Set the window title, size and color window.title('SQL script generator') window.geometry("800x600") window.config(bg="gray") window.resizable(False, False) command_names = ['Delete duplicates while keeping the original', 'Delete duplicates without keeping the original', 'Retrive all data from table', 'Check for duplicates', 'Delete table', 'Copy data from one table to another', 'Update values', 'Add new column to exisitng table'] canvas = Canvas(window) canvas.pack(side='left', fill='both', expand=True) # Create two frames search_frame = Frame(canvas) search_frame.pack(side='top') buttons_frame = Frame(canvas) buttons_frame.pack(side='bottom') canvas.create_window((0, 0), window=buttons_frame, anchor='nw') for i, text in enumerate(command_names): Button(buttons_frame, text=command_names[i], width=40, height=2, command=lambda text = text, index = i: open_window(text, index)).grid(row=i+1, column=0, pady=5, padx=5) buttons_frame.update_idletasks() window.mainloop()
关键修改说明
show_columns函数:- 用
",".join([f"[{col}]" for col in column_names])替代循环拼接,简化代码同时避免末尾多余逗号;若需保留末尾逗号,可修改为",".join(...) + ","。 - 新增返回值逻辑,成功时返回列名字符串,异常时返回空字符串,确保
column变量能被正确赋值。 - 捕获具体异常并打印错误信息,便于调试问题。
- 用
- trace回调逻辑:
- 在lambda表达式中新增
col_var=column参数,将column变量传入回调函数。 - 调用
show_columns(sv.get())后,直接通过col_var.set()将返回值同步到column变量,绑定的Entry3会自动显示该值。
- 在lambda表达式中新增
内容的提问来源于stack exchange,提问作者Igor Karadzic
相关产品推荐
相关产品推荐

