📚 目录 第 5 章 单行输入:Entry 与变量绑定(StringVar)

第 5 章 单行输入:Entry 与变量绑定(StringVar)

本书红线(贯穿全教程,回顾):
1. 每个界面都用 class App: 封装,__init__ 里建控件,方法即事件回调。
2. 所有控件示例一律写在类里,不用脱离类的扁平脚本。
3. 代码块带 if __name__ == "__main__": 守卫,可独立运行。
4. 星级:★ 了解 · ★★ 理解 · ★★★ 掌握 · ★★★★ 重点必会。

主线项目:图形界面通讯录管理器,随章节每章新增一个控件慢慢长大。

上节回顾(第 4 章):你学会了 pack / grid / place 三种布局管理器,能把 Label、Button 排整齐、排成表格,还建立了"用 _build_widgets 把建界面和事件逻辑分离"的 OOP 习惯。不过界面还只能"显示"和"点击",没有地方让用户输入文字。

本章目标:引入第一个能输入的控件——Entry(单行输入框),让用户输入一行文字(比如姓名),程序能读出来。重点是学会变量绑定:用 tk.StringVar() 把"输入框"和"一个变量"双向关联,之后读写都用这个变量,比直接操作 Entry 更 OOP、更清爽。本章还顺带认识 show="*" 做密码框。


5.1 是什么 / 适用场景 ★

是什么:Entry 是一个单行文本框,用户可以在里面打字,程序可以读取或设置里面的文字。它和 Label 相反——Label 只能"看",Entry 可以"写(输入)"。

适用场景:

不适用:要输入一大段文字(如备注、日志),请等第 6 章的 Text 多行控件。


5.2 构造选项(对照官方手册)★★

下面是 Entry 最常用的选项(来自官方 tkinter.Entry 文档):

选项作用常用取值重要度
textvariable绑定一个 StringVar,变量变文字跟着变self.name_var(一个 tk.StringVar())★★★★
show把输入的字符替换成指定符号(做密码框)"*" 或 "●"★★★
width输入框可见宽度(字符数,非像素)整数,如 20★★★
font字体字号元组 ("微软雅黑", 12)★★
fg / bg文字色 / 背景色颜色字符串★★
state是否可编辑"normal"(可编辑,默认)/"readonly"(只读)/"disabled"(禁用)★★★
justify输入文字在框内的对齐"left"(默认)/"center"/"right"★★
relief / borderwidth边框样式 / 粗细"sunken"(默认凹陷) 等★
📌 textvariable 是本章核心:有了它,就不用每次都去 entry.get() 拿文字,而是直接读绑定的 StringVar。详见 5.4 节。

5.3 常用方法速查 ★★

方法作用示例
get()读取输入框当前文字(返回字符串)text = self.entry.get()
insert(索引, 文字)在指定位置插入文字self.entry.insert(0, "默认值")
delete(起始, 结束)删除一段文字(含起始不含结束)self.entry.delete(0, tk.END) 清空全部
config(state=...)运行时改状态(只读/禁用)self.entry.config(state="readonly")
索引规则:Entry 里文字的"位置"从左到右用数字编号,最左边是 0。tk.END 表示"末尾"。所以 delete(0, tk.END) 就是"从第 0 个字符删到末尾"= 清空。

5.4 详细例子(循序渐进)★★★

本章引入 tk.Entry。重点示例都演示 StringVar 绑定,这才是更 OOP 的写法。

例 5.1 最基础的 Entry:点按钮读出输入 ★

先不绑定变量,用 entry.get() 直接读,建立"输入框能读出字"的直觉:

# 第5章 例5.1:一个输入框 + 一个按钮,点按钮把输入的名字打印出来
import tkinter as tk


class App:
    def __init__(self, root):
        self.root = root
        self.root.title("通讯录管理器")

        # 提示文字
        self.tip = tk.Label(self.root, text="请输入姓名:")
        self.tip.pack(pady=5)

        # 单行输入框:width=20 表示可见 20 个字符宽
        self.entry = tk.Entry(self.root, width=20)
        self.entry.pack(pady=5)

        # 按钮:点它调用 on_submit
        self.btn = tk.Button(self.root, text="确定", command=self.on_submit)
        self.btn.pack(pady=5)

    def on_submit(self):
        # 读取输入框当前文字,存进变量 name
        name = self.entry.get()
        print("你输入的姓名是:", name)


if __name__ == "__main__":
    root = tk.Tk()
    App(root)
    root.mainloop()

逐行说明:

例 5.2 StringVar 绑定:输入框 ↔ 变量 双向联动(本章重点)★★★

StringVar 是 tkinter 的"字符串变量"类型。把它绑到 Entry 的 textvariable 上后,输入框内容和这个变量就同步了:用户在框里打字,变量自动更新;程序用 变量.set("xx") 改值,框里也跟着变。

# 第5章 例5.2:用 StringVar 把输入框和变量绑定,读写都通过变量(更 OOP)
import tkinter as tk


class App:
    def __init__(self, root):
        self.root = root
        self.root.title("通讯录管理器")

        # ① 先创建一个 StringVar,作为"姓名"的数据来源
        self.name_var = tk.StringVar()

        self.tip = tk.Label(self.root, text="请输入姓名:")
        self.tip.pack(pady=5)

        # ② 输入框的 textvariable 指向 self.name_var,二者绑定
        self.entry = tk.Entry(self.root, textvariable=self.name_var, width=20)
        self.entry.pack(pady=5)

        self.btn = tk.Button(self.root, text="确定", command=self.on_submit)
        self.btn.pack(pady=5)

    def on_submit(self):
        # ③ 读取时不再调 entry.get(),而是读绑定的变量
        name = self.name_var.get()
        print("姓名变量里的值是:", name)


if __name__ == "__main__":
    root = tk.Tk()
    App(root)
    root.mainloop()

逐行说明:

例 5.3 输入后显示在 Label 上 + 清空输入框 ★★

把例 5.2 升级:点"确定"把姓名显示到一个结果 Label;点"清空"按钮用 delete(0, tk.END) 清掉输入。

# 第5章 例5.3:点"确定"把输入显示到 Label,点"清空"用 delete 清掉输入框
import tkinter as tk


class App:
    def __init__(self, root):
        self.root = root
        self.root.title("通讯录管理器")

        self.name_var = tk.StringVar()
        self.tip = tk.Label(self.root, text="请输入姓名:")
        self.tip.pack(pady=5)

        self.entry = tk.Entry(self.root, textvariable=self.name_var, width=20)
        self.entry.pack(pady=5)

        # 显示结果的 Label,初始提示
        self.result = tk.Label(self.root, text="(结果将显示在这里)", fg="blue")
        self.result.pack(pady=5)

        self.ok_btn = tk.Button(self.root, text="确定", command=self.on_ok)
        self.ok_btn.pack(pady=2)
        self.clear_btn = tk.Button(self.root, text="清空", command=self.on_clear)
        self.clear_btn.pack(pady=2)

    def on_ok(self):
        # 读变量,把姓名显示到结果 Label
        name = self.name_var.get()
        self.result.config(text=f"你好,{name}!")

    def on_clear(self):
        # 清空输入框:从 0 删到末尾
        self.entry.delete(0, tk.END)


if __name__ == "__main__":
    root = tk.Tk()
    App(root)
    root.mainloop()

逐行说明:

例 5.4 密码框(show="*")与默认值 ★★

show="*" 让输入显示为星号,适合密码;insert(0, "默认") 可预设初始文字。

# 第5章 例5.4:密码框(show="*")与预设默认值(insert)
import tkinter as tk


class App:
    def __init__(self, root):
        self.root = root
        self.root.title("通讯录管理器")

        self.pw_var = tk.StringVar()

        tk.Label(self.root, text="密码:").pack(pady=5)
        self.pw_entry = tk.Entry(
            self.root, textvariable=self.pw_var, show="*", width=20   # show="*" 输入显示为星号
        )
        self.pw_entry.pack(pady=5)

        # 预设一个默认值(在位置 0 插入文字)
        self.pw_entry.insert(0, "123456")

        self.btn = tk.Button(self.root, text="显示真实密码", command=self.show_pw)
        self.btn.pack(pady=5)

    def show_pw(self):
        # 虽然界面显示星号,但变量里仍是真实字符
        print("真实密码是:", self.pw_var.get())


if __name__ == "__main__":
    root = tk.Tk()
    App(root)
    root.mainloop()

逐行说明:


5.5 OOP 落点 ★★

一句话:Entry 管"用户打字",StringVar 管"程序读写的那个值",两者绑定后各司其职。

5.6 注意事项 / 易错清单 ★★


5.7 本章练习

  1. 写一个程序:一个 Entry 输入"电话",一个按钮"添加",点按钮把输入打印到控制台。
  2. 在练习 1 基础上,加一个"清空"按钮,用 delete(0, tk.END) 清掉输入框;结果同时显示到一个 Label 上。
  3. 做一个简易登录界面(用 grid 排整齐):用户名 Entry、密码 Entry(show="*")、"登录"按钮;点登录时把两者用 StringVar 读出并打印。
  4. 思考题:例 5.3 里如果把"清空"写成 self.name_var.set("") 而不是 self.entry.delete(0, tk.END),会有什么不同?(提示:两者在已绑定的情况下效果通常一致,但若 Entry 有独立状态或想确保框内视觉清空,用 delete 最直接;理解"变量"与"控件显示"是两个层面。)
下节预告:第 6 章我们认识多行输入控件——Text,用来输入/显示一大段文字(如备注、日志),并学习 get/insert/delete 和用 tag 给文字上色。