17、文字区域Text第5章中的Entry控件主要是处理单行的文字输入本章所要介绍的Text控件可以视为Entry的扩充可以处理多行的输入另外也可以在文字中嵌入图像或是提供格式化功能。因此实际上我们可以将此Text当作简单的文字处理软件甚至也可以当作网页浏览器使用。17-1 文字区域Text的基本概念Text的构造方法如下。Text(父对象, options, ...)参数一同上options参数(1) bg或background背景色彩。(2) borderwidth或bd边界宽度默认是2像素。(3) cursor当鼠标光标在文本框上方时的光标形状。(4) exportselection如果执行选择操作时所选择的字符串会自动输出至剪切板如果想要避免Rubio可以设置exportselection0。(5) fg或foreground字形色彩。(6) font字形。(7) height高单位是字符高实际高度会视字符高度而定。(8) highlightbackground当文本框取得焦点时的背景颜色。(9) highlightcolor当文本框取得焦点时的颜色。(10) highlightthickness取得焦点时的厚度默认值是1.(11) insertbackground插入光标的颜色默认是黑色。(12) insertborderwidth围绕插入游标的3D厚度默认是0.(13) padxText左 / 右框与文字最左 / 最右的间距。(14) padyText上 / 下框与文字最上 / 最下的间距。(15) relief默认是reliefFLAT可由此控制文字外框。(16) selectbackground被选取字符串的背景色彩。(17) selectborderwidth选取字符串时的边界厚度默认值是1.(18) selectforeground被选取字符串的前景色彩。(19) state输入状态默认是NORMAL表示可以输入DISABLED则是无法编辑。(20) tab可设置按Tab键时如何定位插入点。(21) widthText的度单位是字符宽。(22) wrap可控制某行文字太长时的处理默认时wrapCHAR当某行文字太长时可从字符做断行当wrapWORD时只能从字做断行。(23) xscrollcommand在x轴使用滚动条。(24) yscrollcommand在y轴使用滚动条。下面程序实例ch17_1建立一个高度是2宽度是30的Text文字区域然后输入文字并观察执行结果。from tkinter import * root Tk() root.title(ch17_1) text Text(root, height2, width30) text.pack() root.mainloop()执行结果 下面分别是没有输入输入2行数据输入4行数据的结果。从上图可以发现若是输入文字超过两行将导致第一行数据被隐藏若是输入更多行将造成更多文字被隐藏虽然可以用移动光标的方式重新看到第一行文字但是对于不了解程序结构的人而言还是比较容易误会Text文字区域的内容。最后要注意的是放大窗口并不会放大Text文字区域参考下图。当然也可以重新设置Text()方法内的height和width参数让Text文字区域可以容纳更多数据。不过至少在此读者应该可以体会如何使用Text控件建立输入多行文字的程序了。17-2 插入文字insert()insert()可以将字符串插入指定的索引位置它的使用格式如下。insert(index, string)若是参数index位置使用END或是INSERT表示将字符串插入文件末端位置。程序实例ch17_2将字符串插入Text文字区域末端位置。from tkinter import * root Tk() root.title(ch17_2) text Text(root, height3, width30) text.pack() text.insert(END, Python王者归来\nJava王者归来\n) text.insert(END, C王者归来\n) root.mainloop()下面程序实例ch17_3插入一个长为30的字符串并观察执行结果。from tkinter import * root Tk() root.title(ch17_3) text Text(root, height3, width30) text.pack() string dadsadasdasdasdasdasdasfadfaf, dfasdasdfasdfasdagfagdygetgsadrwtrwgasgasgF, FafgADTFGWETGGASGASGHAERGASGgqagasrgajsgasg, gsgsgsdgsdgdsgsfASDTFSAGAGASfafdfdfgadsdfad, fadsfafadfgregshdfujtukyuokgjhmghjkyumgjktt argeshrthfdthsdhsdghsdhsdhtsdthetsuqwuikmdf text.insert(END, string) root.mainloop()执行结果还是只能看到部分字符串内容为了改进此状况可以使用将滚动条Scroll加入此Text控件然后用滚动条方式查看内容可参考17-3内容。17-3 Text加上滚动条Scrollbar设计在12-8节曾说明过滚动条Scrollbar的用法同时也将Scrollbar与Listbox进行过结合我们可以参考该节思想将Scroll应用于Text控件中。下面程序实例h17_4修改ch13_3将原先只显示3行文字改成显示5行文字另外主要是将Scrollbar应用于Text控件中让整个Text文字区域增加y轴的滚动条。监听字符串self.emp_internation.trace_add(write, self.count_salary)self.emp_internation为创建的字符串变量ttk.String()trace_add(write, 函数名)监听字符串变量写入之后需要干什么。表头组件创建表格组件ttk.Treeview(columns[, , ], show)参数表头标识 columns 参数后面可以接列表列表中有几个元素就增加几个表头去除默认表头 showheadingsttk样式组件一、基础使用示例style ttk.Style() # 查看ttk的组件样式 print(style.theme_names()) # ttk组件主题设置 style.theme_use() # 设置默认标签样式 style.configure(TLabel, foregroundred, font(宋体, 16)) # ttk Label组件参数绑定stylelogin-TLabel就可以设置下面样式了 style.configure(login-TLabel, foregroundred, font(宋体, 16)) # 默认按钮样式 style.configure(TButton, font(宋体, 12)) # 默认单选框样式 style.configure(TRadiobutton, font(宋体, 12)) # 默认表头标题 style.configure(Treeview.Heading, font(宋体, 16)) # 默认表内容样式 style.configure(Treeview, font(宋体, 14))ttk.Treeview表格组件一、基础使用示例先看一个完整的代码示例可以直接复制运行import tkinter as tk from tkinter import ttk root tk.Tk() root.title(简易表格示例) # 创建表格 table ttk.Treeview(root) # 定义列注意第一列#0是隐藏的树形列通常留空 table[columns] (姓名, 年龄, 城市) # 设置列属性 table.column(#0, width0, stretchtk.NO) # 隐藏第一列 table.column(姓名, width100, anchortk.W) # 列宽度和对齐方式 table.column(年龄, width60, anchortk.CENTER) table.column(城市, width120, anchortk.E) # 设置表头 table.heading(姓名, text姓名) # 列标题 table.heading(年龄, text年龄) table.heading(城市, text城市) # 添加数据 table.insert(, end, values(张三, 25, 北京)) # 插入一行数据 table.insert(, end, values(李四, 30, 上海)) table.insert(, end, values(王五, 28, 广州)) # 显示表格 table.pack(pady20) root.mainloop()二、核心参数详解1. 列配置column方法width列宽度单位像素anchor对齐方式tk.W左对齐tk.CENTER居中tk.E右对齐minwidth最小宽度可拖动调整列宽时有效stretch是否允许拉伸tk.YES/tk.NOtable.column(姓名, anchorcenter, width90)2. 表头设置heading方法text显示的表头文字command点击表头时触发的回调函数用于排序功能table.heading(年龄, text年龄, commandlambda: sort_by_age())3. 插入数据insert方法parent父节点通常用空字符串表示根节点index插入位置end表示末尾tk.END也可以从最后一行开始追加values数据内容元组形式长度需与列数匹配iid可选参数为行指定唯一标识符table.insert(, end, iidrow1, values(张三, 25, 北京))4. 其他常用方法删除行table.delete(iid)获取选中行table.selection()获取行数据table.item(iid, values)修改数据table.item(iid, values新数据)获取选中行的idtable.identify_row(event.y)获取所有行的idtable.get_children()查询id的下标table.get_children().index(id)三、样式美化1. 修改字体颜色style ttk.Style() style.configure(Treeview, rowheight25, # 行高 font(微软雅黑, 11), foreground#333, background#fff) # 设置斑马线效果隔行变色 style.map(Treeview, background[(selected, #0078D7), (!selected, #f0f0f0)])2. 添加滚动条# 纵向滚动条 y_scroll ttk.Scrollbar(root, orientvertical, commandtable.yview) table.configure(yscrollcommandy_scroll.set) y_scroll.pack(sidetk.RIGHT, filltk.Y) # 横向滚动条同理orienthorizontal四、常见问题为什么表格不显示数据检查是否执行了insert插入数据确认列名与columns定义一致如何实现点击排序需要自定义排序函数def sort_by_col(col, reverse): data [(table.set(child, col), child) for child in table.get_children()] data.sort(reversereverse) for index, (val, child) in enumerate(data): table.move(child, , index) table.heading(col, commandlambda: sort_by_col(col, not reverse))如何获取选中行数据selected table.selection() if selected: print(table.item(selected[0], values))五、完整功能示例带编辑功能# 点击单元格编辑功能 def edit_cell(event): region table.identify_region(event.x, event.y) if region cell: column table.identify_column(event.x) iid table.focus() current_value table.item(iid, values)[int(column[1])-1] # 创建编辑框 entry tk.Entry(root) entry.place(xevent.x, yevent.y) entry.insert(0, current_value) def save_edit(): new_value entry.get() values list(table.item(iid, values)) values[int(column[1])-1] new_value table.item(iid, valuesvalues) entry.destroy() entry.bind(Return, lambda e: save_edit()) table.bind(Double-1, edit_cell)滚动条ttk.Scrollbar用于滚动一些组件的可见范围根据方向可分为垂直滚动条和水平滚动条。组件常常被用于实现文本、画布和列表框的滚动。在名为parent的顶级窗口或框架中创建一个新的滚动条组件:# 创建滚动条 command需要绑定的应用组件yview scroll_bar ttk.Scrollbar(main_window, commandtable.yview) # 表格绑定滚动条 table.config(yscrollcommandscroll_bar.set) # 滚动条布局 scroll_bar.place(x1313, y80, height645)