📚 目录 第 6 章 多行输入:Text(输入/显示大段文字)

第 6 章 多行输入:Text(输入/显示大段文字)

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

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

上节回顾(第 5 章):你学会了 Entry 单行输入,并用 StringVar 把"输入框"和"变量"双向绑定,让程序能读出用户打的字(比如姓名)。但 Entry 只能装"一行",装不下一大段话。

本章目标:认识多行输入控件——Text。它能装下好几段文字,适合做"备注""日志""大文本框"。我们会学怎么取出全部文字、怎么追加、怎么清空,以及用 tag 给一段文字上色(先认识概念)。最后把它和第 5 章的 Entry 做个对比。


6.1 是什么 / 适用场景 ★

是什么:Text 是一个多行文本区域,可以输入、显示、编辑大段文字,支持滚动、不同字体、甚至图文混排(进阶)。它比 Entry 强大得多。

适用场景:

不适用:只填一个值(姓名、电话)用 Entry 就够了;Text 太重。


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

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

选项作用常用取值重要度
height可见行数(行,非像素)整数,如 10★★★★
width可见列数(字符数)整数,如 40★★★★
font字体字号元组 ("微软雅黑", 12)★★★
fg / bg文字色 / 背景色颜色字符串★★★
wrap文字到边界是否换行"word"(按词换行,默认)/"char"(按字符)/"none"(不换行)★★★
state是否可编辑"normal"(可编辑,默认)/"disabled"(只读)★★★
relief / borderwidth边框样式 / 粗细"sunken"(默认凹陷) 等★★
padx / pady文字到边框的内边距(像素)整数★★
📌 wrap="word" 的意义:长行默认按"单词"折行,不会出现把中文词从中间切断的尴尬(配合宽度使用)。想让中文也优雅换行,通常用默认的 wrap="word" 即可。

6.3 常用方法速查 ★★

Text 的方法很多,先掌握这几个核心(注意它的"位置"用 "行.列" 表示,如 "1.0" 指第 1 行开头):

方法作用示例
get(起始, 结束)取出一段文字self.text.get("1.0", tk.END) 取全部
insert(位置, 文字)在指定位置插入文字self.text.insert(tk.END, "新行\n") 末尾追加
delete(起始, 结束)删除一段文字self.text.delete("1.0", tk.END) 清空全部
insert(tk.INSERT, 文字)在"当前光标处"插入self.text.insert(tk.INSERT, "字")
tag_add(标签, 起, 止)给一段文字打上标签(用于上色)self.text.tag_add("hl", "1.0", "1.5")
tag_config(标签, 选项)配置某标签的样式(颜色等)self.text.tag_config("hl", foreground="red")
行号格式 "行.列":Text 里每个字符都有坐标,格式是 "行.列"。行从 1 开始,列从 0 开始。所以 "1.0" = 第 1 行最开头;"2.3" = 第 2 行第 4 个字符前。tk.END 是末尾,tk.INSERT 是当前光标位置。

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

本章用 tk.Text。所有示例写在 class App: 里,并沿用 _build_widgets 的拆分习惯。

例 6.1 基础 Text:输入大段文字并整体读出 ★

# 第6章 例6.1:一个多行文本框 + 按钮,点按钮读出全部文字
import tkinter as tk


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

    def _build_widgets(self):
        tk.Label(self.root, text="联系人备注:").pack(pady=5)

        # 多行文本框:高 10 行、宽 40 字符
        self.text = tk.Text(self.root, height=10, width=40, wrap="word")
        self.text.pack(padx=5, pady=5)

        tk.Button(self.root, text="读取备注", command=self.on_read).pack(pady=5)

    def on_read(self):
        # get("1.0", tk.END):从第 1 行开头取到末尾 = 全部内容
        content = self.text.get("1.0", tk.END)
        print("备注内容是:\n", content)


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

逐行说明:

例 6.2 追加文字与清空(日志风格)★★

模拟一个"日志框":点"追加"在末尾加一行;点"清空"用 delete("1.0", tk.END) 清掉。

# 第6章 例6.2:日志风格——追加一行、清空全部
import tkinter as tk


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

    def _build_widgets(self):
        self.log = tk.Text(self.root, height=8, width=40, state="normal")
        self.log.pack(padx=5, pady=5)

        tk.Button(self.root, text="追加一行", command=self.on_append).pack(pady=2)
        tk.Button(self.root, text="清空日志", command=self.on_clear).pack(pady=2)

    def on_append(self):
        # 在末尾追加一行文字(\n 表示换行,否则接在上次末尾)
        self.log.insert(tk.END, "有新联系人加入\n")

    def on_clear(self):
        # 清空:从第 1 行开头删到末尾
        self.log.delete("1.0", tk.END)


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

逐行说明:

例 6.3 在光标处插入 + 用 tag 给文字上色(概念入门)★★

tk.INSERT 表示"当前光标位置";tag 可以给一段文字单独上色。下面演示:点按钮在光标处插入文字,并把刚插入的文字标红。

# 第6章 例6.3:在光标处插入文字,并用 tag 给该段文字上红色(概念入门)
import tkinter as tk


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

    def _build_widgets(self):
        self.text = tk.Text(self.root, height=8, width=40)
        self.text.pack(padx=5, pady=5)

        # 先定义一个名为 "hl" 的标签样式:前景(文字)红色、加粗
        self.text.tag_config("hl", foreground="red", font=("微软雅黑", 12, "bold"))

        tk.Button(self.root, text="插入高亮文字", command=self.on_insert).pack(pady=5)

    def on_insert(self):
        # 在光标处插入一段文字
        self.text.insert(tk.INSERT, "重要提醒!")
        # 给"刚刚插入的这一段"打上 hl 标签,使其变红加粗
        # 这里简单演示:对当前光标前 5 个字符上色("重要提醒!"正好 5 字)
        end = self.text.index(tk.INSERT)          # 当前光标位置(字符串如 "1.5")
        start = f"{end.split('.')[0]}.{int(end.split('.')[1]) - 5}"
        self.text.tag_add("hl", start, end)


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

逐行说明:


6.5 OOP 落点 ★★

一句话:Entry 装一行、Text 装一整片;两者都是"界面上的可编辑区域",但 Text 能分段、能上色、能做日志。

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


6.7 本章练习

  1. 写一个程序:一个 Text 多行框,一个按钮"显示字数",点按钮用 get("1.0", tk.END) 读出内容并打印(提示:用 len() 计字符数,记得 strip() 去掉末尾换行)。
  2. 做一个"备注编辑器":Text + "清空备注"按钮,用 delete("1.0", tk.END) 清空;再加一个"加载示例"按钮,用 insert(tk.END, "示例备注文字") 填入一段文字。
  3. 用 tag 给 Text 里的某一行文字上蓝色(参考例 6.3,先 tag_config 定义样式,再 tag_add 应用到指定行区间)。
  4. 思考题:为什么 Text 不能像 Entry 那样用 textvariable=StringVar() 绑定?(提示:StringVar 只能保存单行字符串,而 Text 是一整片可分段、可带样式的多行内容,数据模型不匹配,所以 tkinter 只提供 get/insert/delete 这类方法直接操作。)
下节预告:第 7 章我们让界面"换皮肤"——认识 ttk 主题控件模块和 Style 样式对象,把土味原生界面升级成现代风格,并学会统一换肤。