12、列表框Listbox与滚动条Scrollbar列表框(Listbox)是一个显示一系列选项的Widget控件用户可以进行单项或多项的选择。12-1 建立列表框它的使用格式如下。Listbox(父对象, options, ...)参数一同上options参数(1) bg或background背景色彩。(2) borderwidth或bd边界宽度默认是2像素。(3) cursor当鼠标光标在列表框上时的光标形状、(4) fg或foreground字形色彩。(5) font字形(6) height高单位是字符默认是10.(7) highlightcolor当尺度条取得焦点时的颜色。(8) highlightthickness当列表框获得焦点时的厚度。(9) listvariable以变量方式处理选项内容。(10) relief默认是reliefFLAT可由此控制列表框外框默认是SUNKEN。(11) selectbackground被选取字符串的背景色彩。(12) selectmode可以决定有多少选项可以被选以及鼠标拖拽如何影响选项。① BROWSE这是默认值我们可以选择一个选项如果选取一个选项同时拖拽鼠标将造成选项最后的位置是被选取的项目位置。② SINGLE只能选择一个选项可以用单击方式选取不可用拖拽方式更改所选的项目。③ MULTIPLE可以选择多个选项单击项目可以切换是否选择该项目。④ EXTENDED单击第一个项目然后拖拽到最后一个项目即可选择这个区间的一系列选项。单击可以选择第一个项目此时若是按住Shift键并单击另一个项目可以选取区间项目。(13) width宽单位是字符。(14) xscrollcommand在x轴使用此滚动条。(15) yscrollcommand在y轴使用此滚动条。下面程序实例建立列表框1然后使用字符高度5建立列表框2。from tkinter import * root Tk() root.title(ch12_1) root.geometry(300x210) lb1 Listbox(root) lb1.pack(sideLEFT, padx5, pady10) lb2 Listbox(root, height5, reliefraised) lb2.pack(anchorN, sideLEFT, padx5, pady10) root.mainloop()执行结果12-2 建立列表框项目insert()可以使用insert()方法为列表框建立项目这个方法的使用格式如下。insert(index, elements)上述index是项目插入位置如果是插在最后面可以使用END。下面程序实例建立列表框同时为这个列表框建立Banana、Watermelon、Pineapple三个项目。from tkinter import * root Tk() root.title(ch12_2) root.geometry(300x210) lb Listbox(root) lb.insert(END, Banana) lb.insert(END, Watermelon) lb.insert(END, Pineapple) lb.pack(pady10) root.mainloop()执行结果上述程序中第8 ~ 10行是建立列表项目因为只有三个项目所以使用上述方式一次建立一个还不会太复杂但是如果所要建立的项目很多时建议使用list方式先存储项目然后使用for...in循环方式将list内的列表项目插入到列表框。下面程序实例建立含6个项目的列表框程序第3、4行是建立fruits列表第11、12行是分别将列表元素插入列表框内。from tkinter import * fruits [apple, banana, mango, orange, grape] root Tk() root.title(ch12_3) root.geometry(300x210) lb Listbox(root) for fruit in fruits: lb.insert(END, fruit) lb.pack(pady10) root.mainloop()执行结果下面程序实例重新设计ch12_3主要是在第10行使用Listbox()构造方法时增加selectmodeMULTIPLE参数设置这个设置可以让用户选取多个项目。from tkinter import * fruits [apple, banana, mango, orange, grape] root Tk() root.title(ch12_4) root.geometry(300x210) lb Listbox(root, selectmodeMULTIPLE) for fruit in fruits: lb.insert(END, fruit) lb.pack(pady10) root.mainloop()执行结果下面程序实例使用selectmodeEXTENDED参数重新设计ch12_4此时可以用拖拽的方式选取区间项目。如果先单击一个项目然后按住Shift键并单击另一个项目可以选取这个区间内的项目。from tkinter import * fruits [apple, banana, mango, orange, grape] root Tk() root.title(ch12_5) root.geometry(300x210) lb Listbox(root, selectmodeEXTENDED) for fruit in fruits: lb.insert(END, fruit) lb.pack(pady10) root.mainloop()执行结果目前插入选项皆是插在最后面所以语法是insert(END, elements)其实第一个参数是索引值如果将END改为ACTIVE表示是在目前选项前面加入一个项目如果尚未选择选项则此ACTIVE是0.下面程序实例先建立三个选项然后使用insert(ACTIVE, elements...)在目前选项前方建立另外三个选项。from tkinter import * fruits [apple, banana, mango] root Tk() root.title(ch12_6) root.geometry(300x210) lb Listbox(root, selectmodeEXTENDED) for fruit in fruits: lb.insert(END, fruit) lb.insert(ACTIVE, orange, grape) # 在前面补充建立两个项目 lb.pack(pady10) root.mainloop()执行结果请注意第11行一次插入了两个项目的方式。12-3 Listbox的基本操作本节将介绍下列常用的Listbox控件操作的方法。(1) size()传回列表项目的数量可参考12-3-1节。(2) selection_set()选取特定索引值可参考12-3-2节。(3) delete()删除特定索引项可参考12-3-3节。(4) get()传回指定索引项可参考12-3-4节。(5) curselection()传回选取项目的索引可参考12-3-5节。(6) selection_include()检查指定索引是否被选取可参考12-3-6节。12-3-1 列出列表框的选项数量size()下面程序实例参考ch12_5建立列表框然后列出列表框中的项目数量。from tkinter import * fruits [apple, banana, mango, orange, grape] root Tk() root.title(ch12_7) root.geometry(300x210) lb Listbox(root, selectmodeEXTENDED) for fruit in fruits: lb.insert(END, fruit) lb.pack(pady10) print(items数字: , lb.size()) root.mainloop()执行结果 下面是Python Shell窗口中的执行结果。PS E:\code\python\GuiTkinter\ch12 python .\ch12.py items数字: 512-3-2选取特定索引项selection_set()如果selection_set()方法内含一个参数表示选取这个索引项这个功能常被用于在建立好Listbox后设定初次选择的项目。下面程序实例建立一个Listbox然后设定初次的选择项目是索引为0的项目需留意第12行。from tkinter import * fruits [apple, banana, mango, orange, grape] root Tk() root.title(ch12_8) root.geometry(300x210) lb Listbox(root) for fruit in fruits: lb.insert(END, fruit) lb.pack(pady10) lb.select_set(0) # 默认选择第0个项目 root.mainloop()执行结果如果在select_set()方法内有两个参数时则表示选取区间选项第一个参数是区间的起始索引项第二个参数是区间的结束索引项。下面程序实例建立一个Listbox然后设定初次的选择项目是索引为0 ~ 3的项目读者需留意第12行。from tkinter import * fruits [apple, banana, mango, orange, grape] root Tk() root.title(ch12_9) root.geometry(300x210) lb Listbox(root, selectmodeEXTENDED) for fruit in fruits: lb.insert(END, fruit) lb.pack(pady10) lb.select_set(0, 3) # 默认选择第0 ~ 3个项目 root.mainloop()执行结果12-3-3 删除特定索引项delete()如果delete()方法内含一个参数表示删除这个索引项。下面程序实例建立Listbox后删除索引为1的项目原先索引为1的项目是banana经执行后将没有显示因为已经被删除了读者需留意第12行。from tkinter import * fruits [apple, banana, mango, orange, grape] root Tk() root.title(ch12_10) root.geometry(300x210) lb Listbox(root) for fruit in fruits: lb.insert(END, fruit) lb.pack(pady10) lb.delete(1) # 删除索引为1的项目 root.mainloop()执行结果如果在delete()方法内有两个参数时则表示删除区间选项第一个参数是区间的起始索引项第二个参数是区间的结束索引项。下面程序实例建立一个Listbox然后删除索引为1 ~ 3的项目需留意第12行。from tkinter import * fruits [apple, banana, mango, orange, grape] root Tk() root.title(ch12_11) root.geometry(300x210) lb Listbox(root) for fruit in fruits: lb.insert(END, fruit) lb.pack(pady10) lb.delete(1, 3) # 删除索引为1~3的项目 root.mainloop()执行结果12-3-4 传回指定的索引项get()如果get()方法内含一个参数表示传回这个索引项的元素内容。下面程序实例建立Listbox后传回索引为1的项目。from tkinter import * fruits [apple, banana, mango, orange, grape] root Tk() root.title(ch12_12) root.geometry(300x210) lb Listbox(root) for fruit in fruits: lb.insert(END, fruit) lb.pack(pady10) print(lb.get(1)) # 打印索引为1的项目 root.mainloop()执行结果PS E:\code\python\GuiTkinter\ch12 python .\ch12.py banana如果在get()方法内有两个参数时则表示传回区间选项第一个参数时区间的起始索引项第二个参数时区间的结束索引项所传回的值用元组方式传回。下面程序实例建立Listbox后传回索引为1 ~ 3的项目。from tkinter import * fruits [apple, banana, mango, orange, grape] root Tk() root.title(ch12_13) root.geometry(300x210) lb Listbox(root) for fruit in fruits: lb.insert(END, fruit) lb.pack(pady10) print(lb.get(1, 3)) # 打印索引为1 ~ 3的项目 root.mainloop()执行结果PS E:\code\python\GuiTkinter\ch12 python .\ch12.py (banana, mango, orange)12-3-5 传回所选取项目的索引curselection()这个方法会传回所选取项目的索引。下面监听字符串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)