Tkinter地址簿系统问题:选ComboBox姓名后Entry显示Cursor对象而非手机号
解决Tkinter地址簿中Entry显示Cursor对象的问题
嘿,我一眼就看出问题所在了——你是把SQL查询返回的Cursor对象直接塞进Entry里了,而不是从Cursor里提取出实际的电话号码数据!这就是为什么你看到<sqlite3.Cursor object at 0x102e09f10>这种奇怪的输出。
问题根源
当你执行cursor.execute()时,它返回的是一个Cursor实例,而不是查询结果本身。你需要调用Cursor的方法(比如fetchone()、fetchall())来获取真正的数据。
修正步骤及代码示例
假设你的MyList类里有处理ComboBox选中事件的逻辑,下面是修正后的完整实现:
import tkinter as tk from tkinter import ttk import sqlite3 class MyList: def __init__(self, root): self.root = root # 初始化数据库连接 self.conn = sqlite3.connect("address_book.db") self.cursor = self.conn.cursor() # 创建ComboBox并加载姓名数据 self.name_combo = ttk.Combobox(root, state="readonly") self.name_combo.pack(pady=10) self.load_names_to_combo() # 创建显示电话号码的Entry self.phone_entry = ttk.Entry(root, width=20) self.phone_entry.pack(pady=10) # 绑定ComboBox选中事件 self.name_combo.bind("<<ComboboxSelected>>", self.on_name_selected) def load_names_to_combo(self): # 从数据库拉取所有姓名并填充到ComboBox self.cursor.execute("SELECT name FROM contacts") names = [row[0] for row in self.cursor.fetchall()] self.name_combo['values'] = names def on_name_selected(self, event): selected_name = self.name_combo.get() # 使用参数化查询,避免SQL注入和语法错误 self.cursor.execute("SELECT phone FROM contacts WHERE name = ?", (selected_name,)) # 获取匹配的第一条结果(元组形式),无结果则返回None phone_record = self.cursor.fetchone() # 更新Entry内容 self.phone_entry.delete(0, tk.END) if phone_record: # 取元组的第一个元素,就是对应的电话号码 self.phone_entry.insert(0, phone_record[0]) else: # 处理无匹配数据的情况 self.phone_entry.insert(0, "未找到对应号码") def __del__(self): # 程序结束时关闭数据库连接 self.conn.close() if __name__ == "__main__": root = tk.Tk() root.title("地址簿系统") app = MyList(root) root.mainloop()
关键注意事项
- 参数化查询:永远不要用字符串拼接构造SQL语句(比如
"SELECT phone FROM contacts WHERE name = '" + selected_name + "'"),这会带来SQL注入风险,还可能因为姓名里的特殊字符引发语法错误。 - 结果判断:
fetchone()返回查询到的第一条记录(元组),如果没有匹配结果则返回None,一定要做判断避免报错。 - 资源管理:记得在类销毁时关闭数据库连接,或者使用
with语句自动管理游标和连接。
内容的提问来源于stack exchange,提问作者Danso Adjei
相关产品推荐
相关产品推荐

