You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter+Sqlite3调用Entry.get()报NameError变量未定义错误

问题核心原因

你遇到的NameError: name 'earn' is not defined报错本质是变量作用域不匹配:earn、earning_value两个输入框控件是定义在earning()函数内部的局部变量,全局作用域下的submit()函数没有权限访问这两个变量,自然调用.get()时会提示名称不存在。

除了这个直接触发报错的问题,你的代码还有5处会导致运行异常的硬伤:

  • 缩进不符合Python语法:earning()函数内部的所有代码没有做缩进,Python靠缩进识别代码块归属,直接运行会先报语法错误
  • Entry控件的textvariable参数传值错误:该参数要求接收Tkinter提供的StringVar/DoubleVar类型变量,你直接传入字符串'earn'/'earning_value'没有任何实际作用
  • SQL插入语句字段数不匹配:你创建的calculate表设置了5个非空字段,但插入语句只传了2个值,就算解决变量问题也会触发SQL字段数不匹配的报错
  • 存在SQL注入风险:用f-string直接拼接用户输入到SQL语句中,只要输入内容包含单引号等特殊字符就会搞崩SQL语句,还存在数据泄露风险
  • 数据库操作逻辑错误:事务提交方法属于数据库连接对象,不是游标对象,你写的c.commit()本身就无法正常执行;另外操作完成后只关闭了游标,没有关闭数据库连接,会导致连接泄漏。
修复后可直接运行的代码
from tkinter import *
from tkinter import ttk
import sqlite3

# 程序启动时初始化数据库建表,执行一次即可
conn = sqlite3.connect("track.db")
c = conn.cursor()
c.execute("""
    CREATE TABLE IF NOT EXISTS calculate
    (
        earn TEXT NOT NULL,
        expense TEXT NOT NULL,
        earning_value REAL NOT NULL,
        expense_value REAL NOT NULL,
        bank_balance REAL NOT NULL
    )
    """)
conn.commit()
conn.close()

def earning():
    new_window = Toplevel()
    new_window.geometry("400x400")
    
    # 收入来源输入框
    text1 = Label(new_window, text="From where did you earn?")
    text1.pack() 
    earn = Entry(new_window)
    earn.pack()
    
    # 收入金额输入框
    text2 = Label(new_window, text="How much did you earn?")
    text2.pack() 
    earning_value = Entry(new_window)
    earning_value.pack()

    # 提交逻辑放在earning函数内部,可直接访问同作用域的输入控件
    def submit():
        # 基础输入校验
        earn_content = earn.get().strip()
        earn_val_content = earning_value.get().strip()
        if not earn_content or not earn_val_content:
            Label(new_window, text="输入不能为空", fg="red").pack()
            return
        try:
            earn_val = float(earn_val_content)
        except ValueError:
            Label(new_window, text="收入金额请输入数字", fg="red").pack()
            return

        conn = sqlite3.connect('track.db')
        c = conn.cursor()
        # 参数化查询避免注入,补全5个非空字段的传值,其余字段可后续加对应输入框采集
        c.execute(
            "INSERT INTO calculate VALUES (?, ?, ?, ?, ?)",
            (earn_content, "", earn_val, 0.0, 0.0)
        )
        conn.commit()
        c.close()
        conn.close()
        Label(new_window, text="提交成功", fg="green").pack()

    submit_button = Button(new_window,text='Submit',command=submit)
    submit_button.pack()

# 主窗口逻辑
window = Tk()
window.geometry("300x200")
main_btn = Button(window, text="录入收入", command=earning)
main_btn.pack(pady=50)
window.mainloop()
关键修改说明
  • 把submit()函数移动到earning()函数内部定义,和两个输入控件处于同一作用域,直接访问控件对象获取输入值,从根源解决名称未定义的报错
  • 修正所有代码缩进,符合Python语法规范
  • 移除无效的textvariable字符串传参,直接通过Entry控件的.get()方法获取用户输入
  • 改用?占位符的参数化查询写法,彻底避免SQL注入和特殊字符导致的语法错误,同时补全5个表字段对应的传值
  • 修正事务提交、连接关闭的逻辑,增加基础输入校验,避免空值、非数字输入导致程序崩溃
  • 补全主窗口入口逻辑,添加触发收入录入窗口的按钮,修复原代码中earning()函数从未被调用、窗口无法打开的问题
  • 移除开头多余的from curses import window导入,避免和Tkinter窗口对象命名冲突

内容的提问来源于stack exchange,提问作者Nayan Roy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 03:15:47