Tkinter 本身不提供数据库连接能力,它只是 GUI 工具包;真正负责连接 SQLite 的是 Python 标准库中的 sqlite3 模块。

为什么不能直接用 Tkinter 连接数据库?
Tkinter 本身不提供数据库连接能力,它只是 GUI 工具包。真正负责连接 SQLite 的是 Python 标准库中的 sqlite3 模块。常见误区是以为 Tkinter 有内置 DB 接口,结果卡在 import 或报错 AttributeError: module 'tkinter' has no attribute 'connect'。
正确做法是:用 sqlite3.connect() 获取连接,再把查询结果塞进 Tkinter 控件(比如 Treeview 或 Listbox)里显示。
怎么把查询结果填进 Treeview?
Treeview 是展示表格数据最常用的选择,但新手常忽略列定义和数据插入顺序,导致表头空白或数据错位。
- 必须先用
tree['columns'] = ('id', 'name', 'age')显式声明列名,再调用tree.heading()设置表头 - 插入数据时,
tree.insert('', 'end', values=row)中的row必须是元组或列表,且长度与列数严格一致 - 别漏掉
tree.column('#0', width=0, stretch=False)隐藏默认 ID 列,否则会多出一列空序号
示例片段:
立即学习“Python免费学习笔记(深入)”;
import tkinter as tk
from tkinter import ttk
import sqlite3
<p>root = tk.Tk()
tree = ttk.Treeview(root, columns=('id', 'name', 'age'), show='headings')
tree.heading('id', text='ID')
tree.heading('name', text='姓名')
tree.heading('age', text='年龄')
tree.pack()</p><p>conn = sqlite3.connect('example.db')
cur = conn.cursor()
cur.execute('SELECT id, name, age FROM users')
for row in cur.fetchall():
tree.insert('', 'end', values=row) # 注意:values 参数必须是可迭代对象
conn.close()
root.mainloop()执行 INSERT/UPDATE 后界面不刷新怎么办?
很多人写完 cur.execute("INSERT ...") 就以为数据自动更新到界面上了,结果 Treeview 还是旧的——因为 GUI 和数据库是两个独立状态,没手动刷新就不会同步。
- 每次增删改后,必须重新查询并清空 + 重填
Treeview,不能只靠conn.commit() - 清空用
for item in tree.get_children(): tree.delete(item),别用tree.delete(*tree.get_children())(语法错误) - 如果用了
fetchall()缓存结果,记得在操作后重新execute查询,而不是复用旧结果
容易被忽略的是事务隔离:SQLite 默认是 autocommit 关闭状态,INSERT 后不 commit(),其他连接(包括你马上要查的那一次)可能看不到新数据。
中文乱码或字段名显示异常的根源在哪?
SQLite 数据库文件本身不存字符编码信息,Python sqlite3 模块默认用 UTF-8 解析文本,但如果你的数据库是用其他工具(如 DB Browser)以 GBK 创建的,或者 Python 脚本文件编码不是 UTF-8,就会出现方块字或问号。
- 确认脚本文件保存为 UTF-8(无 BOM),编辑器里看右下角编码标识
- 避免在 SQL 字符串里硬写中文字符串,改用参数化:
cur.execute("INSERT INTO users(name) VALUES (?)", ("张三",)) -
Treeview表头中文正常,但数据显示为乱码?大概率是数据库读取时解码失败,可强制指定连接编码(虽非常规,但应急可用):conn = sqlite3.connect('db.db'); conn.text_factory = str
真正稳定的做法是统一全程 UTF-8:建库时用 UTF-8 工具、Python 文件存 UTF-8、SQL 语句参数化传入、不依赖隐式编码猜测。


















