Tkinter结合SQLite插入数据报`probably unsupported type`错误如何解决
问题原因
- 缩进错误:你写的
entry_dict定义、Entry创建循环、提交按钮创建的代码缩进错误,不在__init__方法内部,属于类属性而非实例属性,初始化时无法正确调用self参数 - 未存储Entry实例:循环创建Entry控件时,只是临时赋值给了循环变量,没有把控件实例保存到
entry_dict中,导致提交时self.entry_dict.get('Date')拿到的是存储位置配置的字典,不是Entry控件,更不是输入的内容 - 未调用Entry的get()方法获取输入值:就算拿到了Entry控件,也需要调用
.get()方法才能获取输入框中的文本内容,文本转数值类型还需要显式转换,匹配SQLite表中定义的integer字段类型 - 重复关闭数据库连接:你在submit方法里直接关闭了数据库连接,第二次点击提交会报错,建议把关闭连接的逻辑放到类的析构方法或者窗口关闭的回调中
修复后的代码
import tkinter as tk from tkinter import GROOVE import sqlite3 class RawMaterials: def __init__(self, master): # 原代码缺失Frame创建逻辑,补充后可正常渲染 self.myFrame = tk.Frame(master) self.myFrame.pack(padx=20, pady=20) self.conn = sqlite3.connect('qualitycontrol.db') self.c = self.conn.cursor() # 缩进修正,放到__init__方法内部 self.entry_dict = { 'Date': {'master' : self.myFrame, 'column' : 1, 'row' : 0}, 'PO Number': {'master' : self.myFrame, 'column' : 1, 'row' : 1}, 'stock Code': {'master' : self.myFrame, 'column' : 1, 'row' : 2}, 'Batch': {'master' : self.myFrame, 'column' : 1, 'row' : 3}, 'Sample Recieved': {'master' : self.myFrame, 'column' : 1, 'row' : 4}, 'Test': {'master' : self.myFrame, 'column' : 1, 'row' : 5}, 'Result': {'master' : self.myFrame, 'column' : 1, 'row' : 6}, 'Comments': {'master' : self.myFrame, 'column' : 1, 'row' : 7} } for field, info in self.entry_dict.items(): # 创建Entry后将实例存入字典,方便后续取值 entry = tk.Entry(master=info['master'], relief=GROOVE) entry.grid(row=info['row'], column=info['column'], padx=10, pady=5) self.entry_dict[field]['entry'] = entry # 可选:补充字段标签,提升界面易用性 tk.Label(info['master'], text=field).grid(row=info['row'], column=0, padx=10, pady=5) # 缩进修正,放到__init__方法内部 self.submitButton = tk.Button(self.myFrame, text="Submit", relief=GROOVE, command = self.submit, width=30) self.submitButton.grid(row=8, column=0, padx=10, pady=5, columnspan=2) def submit(self): # 取值时调用get()方法,数值类型字段显式转int匹配表结构 self.c.execute("INSERT INTO RawMaterials VALUES (:date, :po, :stock, :batch, :recieved, :test, :result, :comment)", { 'date': int(self.entry_dict['Date']['entry'].get()), 'po': int(self.entry_dict['PO Number']['entry'].get()), 'stock': int(self.entry_dict['stock Code']['entry'].get()), 'batch': int(self.entry_dict['Batch']['entry'].get()), 'recieved': int(self.entry_dict['Sample Recieved']['entry'].get()), 'test': self.entry_dict['Test']['entry'].get(), 'result': self.entry_dict['Result']['entry'].get(), 'comment': self.entry_dict['Comments']['entry'].get(), }) # 仅提交事务,不关闭连接避免二次提交报错 self.conn.commit() # 窗口销毁时再关闭数据库连接 def __del__(self): self.conn.close() # 测试运行代码 if __name__ == "__main__": root = tk.Tk() app = RawMaterials(root) root.mainloop()
额外注意事项
- 建议增加输入合法性校验,避免用户输入非数字内容到数值字段时触发类型转换报错
- 建表语句要确保在类初始化之前执行,或者放到类初始化的开头,避免表不存在的报错
内容的提问来源于stack exchange,提问作者user15004852
相关产品推荐
相关产品推荐

