Python GUI设计 tkinter 笔记
程序员文章站
2022-04-12 09:46:45
...
# 《Python GUI设计 tkinter菜鸟编程》学习笔记,可直接执行代码
# 排版混乱,可设置Tab缩进为2个空格查看
from tkinter import *
# 创建窗口实例
root = Tk()
#也可以用 import tkinter ;root = tkinter.Tk()的形式,但所有对象的方法前都要加tkinter.
# 设置窗口标题
root.title("GUI_NOTE")
# 窗口大小
root.geometry("300x160")
#窗口居中的方法:
width = root.winfo_screenwidth() #获取屏幕宽度
height = root.winfo_screenheight() #获取屏幕高度
w = 300 #程序窗口的宽
h = 160
x = (width-w)/2
y = (height-160)/2
root.geometry("%dx%d+%d+%d" %(w,h,x,y))
# 窗口颜色
root.configure(bg='yellow')
"""
窗口相关方法 说明
title() 设置窗口标题
geometry("宽x高+x轴偏移+y轴便宜") 设置窗口大小和设置窗口在屏幕的位置
maxsize(宽,高) 拖拽时可以设置窗口最大的宽和高
minsize(宽,高) 拖拽时可以设置窗口最小的宽和高
configure(bg="color") 设置窗口背景颜色,也可以用16进制表示,详细查RGB色彩表
resizable(True,True) 设置是否更改窗口大小,第一个参数为宽,第二个为高;若固定窗口可以resizable(0,0)
state("zoomed") 最大化窗口
iconify() 最小化窗口
iconbitmap("xx.ico") 更改默认窗口图标
"""
# widget :控件、组件或部件,窗口建立后下一步创建控件
#---------------------------------------标签----------------------------------------
# 标签Label: Lable(父对象,options,....)父对象为窗口容器,option为可选参数:
"""
(1) anchor:如果空间大于标签时,控制标签位置,默认为center居中,n,ne,e,se,s,sw,w,nw(8个方向顺时针)
(2) bg:背景颜色
(3) bd:标签边界宽度,默认为1
(3) fg:前景色彩(即标签颜色或文字颜色)
(4) font:可选择字型样式和大小font参数包含以下内容(文本顺序写入,空格分隔;或者输入元组):
1.字形:如helvetica、times等可以在word内查询
2.大小:单位是像素(随着字体大小变化width、height也跟着联动变大变小)
3.weight:如 bold、normal(黑体、标准)
4.slant:只有italic和roman(倾斜)
5.underline:例如True、False (下划线)
6.overstrike:例如True、False (一种HTML排版 不懂)
(5) height:标签高度,单位是字符(即文本框高度)
(6) image:标签以图片的方式呈现
(7) text:标签内容,用换行符分行
(8) textvariable:可以设置标签以变量的方式显示
(9) underline:可以设置第几个文字有下划线,从0开始,默认为-1,表示无下划线
(10)width:标签宽度,单位是字符(即文本框宽度)
(11)wraplength:文本到多少宽度后换行,单位像素。
(12)justify:在多行的文本中设置最后一行的位置默认为center;left、right
(13)relief:可以控制标签的边框,可以应用在许多widget控件上,默认relief=FLAT;groove、raised、ridge、solid、sunken
(14)padx、pady:设置标签文字左右和上下边界与标签区间的x轴的距离(就是文字和“标签边框”的距离,不是和窗口的距离)
(15)compound:设置标签内图片和文字时彼此的位置关系,例如compound="lift"图像靠左,right,top,bottm,center(文字覆盖上面)
在设计程序时,可以将上面 参数作为属性设置
"""
label=Label(root,text="I like tkinter",bg='red',anchor="nw",fg="blue",height=3,
width=14,font=('times 20 normal'),relief='raised') #Label方法L必须大写
label.pack() #.pack() 包装窗口的widget控件和定位窗口对象
""" 直接label=Label().pack()窗口效果一样,但因为前面赋予了变量给label所以对象类型已经非
tkinter.Label,所以不建议合并一起修改;"""
#可以用photoimage()方法建立图像对象
imagebj = PhotoImage(file="xxx.png") #Label(root,image=imagebj)用图片作为标签
# 让程序持续运行,并进入等待与处理窗口事件(一般放在程序最后一行)
root.mainloop()
# config():widget的共同方法,更新或者补充widget属性的方法,用法和参数与label一样:
counter = 0 #计数的全局变量
def run_counter(digit):
"""一个计算器"""
def counting():
global counter # global 使用全局变量
counter += 1
digit.config(text=str(counter)) #用于更新或设置widget控件属性
digit.after(1000,counting) #隔一秒后调用counting
counting()
root2 = Tk()
root2.title("root2")
digit=Label(root2,bg="yellow",fg="blue",height=3,width=10,font=("helvetic 20 bold"))
digit.pack()
run_counter(digit) # 调用run_counter函数
print(digit.keys()) # keys()是widget的共同方法,可以打印Label()方法内所有的参数
digit.mainloop()
# separator() 分隔线,P30
#-----------------------------------窗口控件配置管理员-----------------------------------
"""在GUI设计中有三种方法包装和定位各组件在容器或窗口内的位置,这三种方法称为窗口控件管理员:
(1):pack()方法 ; (2):grid()方法 ; (3):place()方法"""
"""
一、pack()方法使用相对位置概念,控件的正确位置有pack方法自动完成,具体参数:
1.side:可以设置垂直或水平配置控件,默认为由上到下(TOP);由下往上(BOTTOM),
由左往右排列(LEFT),由右往左排列(RIGHT),多个控件还可以混合多种参数。
2.fill:参数告诉pack管理程序,设置控件填满所分配容器区间的方式,fill=X表示控件填满所分配的X轴不留白
fill=Y表示填满Y轴,fill=BOTH表示控件可以填满所有分配的空间,默认为NONE表示保持原大小。
3.padx/pady:参数设定控件边界与容器的距离或是控件边界之间的距离,默认窗口下距离是1像素,表示
当前控件与其他控件或容器边界的X轴和Y轴的距离
4.ipadx/ipady:参数可以控制标签文字与标签容器的XY的轴间距(就是文字与控件的距离)
5.anchor:设定widget控件在窗口总的位置,概念与标签中的anchor参数相似,区别在于此处是控件相对于
容器的位置,默认为center;N,NE,E,SE,S,SW,W,NW(8个方向顺时针,大写)
6.expand:参数设定widget控件是否填满额外的父容器空间,默认为False(或0),True或1表示填满(拉伸窗口填满)。
side、fill、expand参数相互影响
"""
# pack示例:
pack_ = Tk()
pack_.title("pack方法")
lab1 = Label(pack_,text="明志科技大学",bg="lightyellow")
lab2 = Label(pack_,text="长庚大学",bg="lightgreen")
lab3 = Label(pack_,text="长庚科技大学",bg="lightblue")
lab1.pack(side=LEFT,fill=Y) # 从左开始排泄,然后占满Y轴
lab2.pack(fill=X,padx=6) # 默认从上往下,然后占满X轴,与容器或控件边框的X轴间距设置为6
lab3.pack(fill=BOTH,expand=True) # 默认从上往下,XY轴全部占满,另外填充额外父容器空间。
print(pack_.pack_slaves()) #打印所有widget控件对象
# !!!!pack() 参数值不需要双引号和Label参数不同,同时注意大小写,基本全部为大写
pack_.mainloop()
"""
pack()为py tkinter中的一个类,所以他提供以下方法:
1.slaves():传回所有widget控件对象(不知道为什么和上面不一样)
2.forget():隐藏widget控件,可以用pack(option,..)复原显示
3.info():传回pack选项的对应值
4.location(x,y):传回词典是否在单元格内,如果是 传回左边,如果不是传回(-1,-1)
5.size():传回widget控件大小
6.propagate(boolean):参数是True表示父窗口大小由控件决定,默认为True
"""
# grdi()实现建立色彩标签:
color = Tk()
color.title("颜色")
colors = ["red","orange","yellow","green","blue","purple"]
r=0
for c in colors:
Label(color,text=c,relief="groove",width=20).grid(row=r,column=0)
Label(color,bg=c,relief="ridge",width=20).grid(row=r,column=1)
r += 1
[5]
color.mainloop()
"""
二、 grid()方法:是一种格状或类始于excel电子表格的包装和定位窗口组件的方法,具体参数:
1.row/column:相当于二维表格的行和列的意思(相同列的宽度根据当前列中宽度最大的,小的居中对齐);
2.columnspan:将某行的多个列的标签位置合并,xx.grid(row=0,column=1,columnspan=2)合并(0,1)和(0,2)
3.rowspan:将某列的多个行的的标签合并;
4.padx/pady:各控件间的距离,单位像素。
5.sticky:参数功能类似于anchor但只能设定N/S/W/E(上下左右),但sticky参数可以通过组合使用:
sticky=N+S:可以拉长高度让控件在顶端和低端对齐
sticky=W+E:可以拉长宽度让控件左边和右边对齐
sticky=N+S+E:可以拉长高度让控件在顶端和低端对齐,同时切齐右边
sticky=N+S+W:可以拉长高度让控件在顶端和低端对齐,同时切齐左边
sticky=N+S+W+E:可以拉长高度让控件在顶端和低端对齐,同时切齐左右两边
"""
"""
rowconfigure()和columnconfigure():使用这两个方法设定第几个row或column的缩放比例:
rowconfigure(0,weight=1): row 0的控件当窗口改变大小事时放比是1
columnconfigure(0,weight=1): column 0的控件当窗口改变大小时缩放比是1
"""
suofang = Tk()
suofang.title("缩放")
# 配合sticky参数使用,实现拉伸窗口时控件跟着扩展
suofang.rowconfigure(1,weight=1)
suofang.columnconfigure(0,weight=1)
lab1 = Label(suofang,text="Label_1",bg="pink")
lab1.grid(row=0,column=0,padx=5,pady=5,sticky=W)#修改为W+E拉伸窗口时同样会有扩展效果
lab2 = Label(suofang,text="Label_2",bg="lightblue")
lab2.grid(row=0,column=1,padx=5,pady=5)
lab3 = Label(suofang,bg="yellow")
lab3.grid(row=1,column=0,columnspan=2,padx=5,pady=5,sticky=N+S+W+E) #让上下左右对齐
suofang.mainloop()
"""
三、place()方法:直接指定将控件放在容器中的方法(使用绝对左边或相对坐标),具体参数:
1.x/y:直接指定控件位置,单位像素,左上角为(0,0)往右下角递增。
2.width/height:可以直接设定插入图像大小,单位像素
3.relx/rely:相对位置(相对于容器内的位置)值0.0~1.0,左上角两个参数值都是0
4.relwidth/relheitht:相对大小(相对于容器内的大小),值为0.0~1.0.
书上推荐使用spak和grid方法。
"""
#-----------------------------------功能按钮 Button----------------------------------
"""
Button(父对象,options,.....),具体参数:绝大部分参数与Label相同,下面几个特有的
1.highlightbackground:当功能按钮取得焦点时的背景颜色
2.highlightcolor:当功能按钮取得焦点时的颜色
3.command:单击功能按钮时,执行此方法。(执行相应函数)command=root.destroy(关闭root窗口,关闭程序),
quit(关闭py内部shell,但root窗口还在执行)
"""
def bColor(bgColor):
root.config(bg=bgColor)
root =Tk()
root.title("按钮,变色")
root.geometry("300x200")
exitbtn = Button(root,text="exit",command=root.destroy)
bluebtn = Button(root,text="blue",command=lambda:bColor("blue"))
yellowbtn = Button(root,text="yellow",command=lambda:bColor("yellow"))
exitbtn.pack(anchor=S,side=RIGHT,padx=5,pady=5)
bluebtn.pack(anchor=S,side=RIGHT,padx=5,pady=5)
yellowbtn.pack(anchor=S,side=RIGHT,padx=5,pady=5)
root.mainloop()
#----------------------------------------文本框 Entry-----------------------------------------
"""
Entry(父对象,option,.....):可输入的单行的文本框,大部分参数与Label相同,下面列取几个特殊的:
1.command:当用户更改内容时,会自动执行此函数。
2.exportselection:如果执行选取时,所选字符串会自动输入值剪贴板,如果想要避免,可以设置为0。
3.highlightbackground:当文本框获取焦点时的背景颜色(鼠标对着时)
4.highlightcolor:当文本框获取焦点是的文字颜色
5.selectbackground:被选取时字符串背景颜色。
6.selectborderwidth:被选取时边界宽度,预设是1.
7.selectfroeground:被选取是字符串颜色。
8.show:显示输入字符,例shou='*',类似于输入密码显示*号。
9.state:输入状态,NORMAL表示可以输入,DISABLE则表示无法输入
10.textvariable:文字变量
11.xscrollcommand:在X轴使用滚动条。
Entry的方法:
1.get():获取当前Entry的字符串类容
2.insert(index,s):在Entry文本框内建立默认文字,s是插入的字符串,index为插入index的位置;
通常作用在Entry()方法建立万文本框后。
3.delete(fast,last=None):删除Entry内从fast字符到last-1之间的字符,删除整个用delete(0,END)
4.eval():计算数学表达式函数,不能说是Entry的方法,是py通用函数,往括号内输入数学表达式字符串,输出结果。
"""
#创建一个获取输入框然后打印在pyshell上的函数
def printInfo():
print("Account: %s\npassword: %s" % (accountE.get(),pwdE.get()))
Entry_=Tk()
Entry_.title("文本框")
msg = "欢迎登录XXXXXX"
logo = Label(Entry_,text=msg)
accountL = Label(Entry_,text="Account")
accountL.grid(row=1) #tkinter会默认补上column=0
PwdL = Label(Entry_,text="Password")
PwdL.grid(row=2)
logo.grid(row=0,column=0,columnspan=2,pady=10,padx=10) #最上面的标签
accountE = Entry(Entry_)
pwdE = Entry(Entry_,show="*") #隐藏密码为*
accountE.insert(0,"请输入帐号") #输入框内默认文字
pwdE.insert(0,"请输入密码")
accountE.grid(row=1,column=1)
pwdE.grid(row=2,column=1,pady=10)
loginbtn = Button(Entry_,text="Login",command=printInfo) #按钮运行上面的打印函数
loginbtn.grid(row=3,column=0,sticky=W,pady=5)
quitbtn = Button(Entry_,text="Quit",command=root.quit) #按钮退出py程序
quitbtn.grid(row=3,column=1,sticky=W,pady=5)
Entry_.mainloop()
#-----------------------------------变量类别--------------------------------------
"""
想要更改将widget内容以变量的方式赋予可以用textvarsible,但要借组TK模块内的变量类别:
x = IntVar() 整型变量,默认是0
x = DoubleVar() 浮点型变量,默认是0.0
x = StringVar() 字符串变量,默认是""
x = BooleanVar() 布尔变量,True是1,False是0
可以使用.get()获取得变量内容,使用.set()方法设置变量内容
变量追踪函数trace():
XX.trace("w",函数):当变量XX被更改时,执行参数内函数(变动追踪)
XX.trace("r",函数):当变量XX被读取时,执行参数内函数(读取追踪)
之所以用textvariable=xx参数的目的,可以理解为将该对象以变量的型式赋予给某个变量,
然后这个变量就可以直接被xx.get()参数获取
"""
def callbacKW(*arges):
xL.set(xE.get()) #不怎么明白这里的xE.get()怎么不算被读取
def callbacKR(*arges):
print("warning:数据被读取!")
def hit():
print("读取数据:",xE.get())
root = Tk()
root.title()
xE = StringVar()
entry = Entry(root,textvariable=xE) #xE设为Entry的变量内容
entry.pack(pady=5,padx=10)
xE.trace("w",callbacKW) #跟踪变量xE,若是被更改则执行函数callbacKW
xE.trace("r",callbacKR) #跟踪变量xE,若是被读取则执行函数callbacKW
xL = StringVar() #将xL变量赋予为字符串型,默认为""
#Entry的变量被更改时,会被追踪执行callbacKW,从而设定Label显示内容
label = Label(root,textvariable=xL)
xL.set("同步显示") #设定XL的初始显示,
label.pack(pady=5,padx=10)
#按钮执行函数hit,会引发变量被读取,而执行函数callbacKR
btn = Button(root,text="读取",command=hit)
btn.pack(pady=5)
root.mainloop()
# 简易计算器的设计:
#执行计算并显示计算结果
def calculate():
result = eval(equ.get())
equ.set(equ.get()+"=\n"+str(result))
# 不断更新显示的计算式
def show(buttonString):
content = equ.get()
if content == "0": #开始输入时,如果是0则不显示0
content=""
equ.set(content + buttonString)
# 功能键C,删除前一个字符
def backspace():
equ.set(str(equ.get()[:-1]))
# 清除显示区
def clear():
equ.set("0")
root = Tk()
root.title("简易计算器")
equ = StringVar()
equ.set("0")
# 设计显示区
label = Label(root,width=50,height=4,relief="raised",anchor=SE,textvariable=equ)
label.grid(row=0,column=0,columnspan=4,padx=5,pady=5)
# 清除显示区按钮
clearButton = Button(root,text="C",fg="blue",width=10,command=clear)
clearButton.grid(row=1,column=0)
# 其他按钮
Button(root,text="DEL",width=10,command=backspace).grid(row=1,column=1)
Button(root,text="%",width=10,command=lambda:show("%")).grid(row=1,column=2)
Button(root,text="/",width=10,command=lambda:show("/")).grid(row=1,column=3)
Button(root,text="7",width=10,command=lambda:show("7")).grid(row=2,column=0)
Button(root,text="8",width=10,command=lambda:show("8")).grid(row=2,column=1)
Button(root,text="9",width=10,command=lambda:show("9")).grid(row=2,column=2)
Button(root,text="*",width=10,command=lambda:show("*")).grid(row=2,column=3)
Button(root,text="4",width=10,command=lambda:show("4")).grid(row=3,column=0)
Button(root,text="5",width=10,command=lambda:show("5")).grid(row=3,column=1)
Button(root,text="6",width=10,command=lambda:show("6")).grid(row=3,column=2)
Button(root,text="-",width=10,command=lambda:show("-")).grid(row=3,column=3)
Button(root,text="1",width=10,command=lambda:show("1")).grid(row=4,column=0)
Button(root,text="2",width=10,command=lambda:show("2")).grid(row=4,column=1)
Button(root,text="3",width=10,command=lambda:show("3")).grid(row=4,column=2)
Button(root,text="+",width=10,command=lambda:show("+")).grid(row=4,column=3)
Button(root,text="0",width=24,command=lambda:show("0")).grid(row=5,column=0,columnspan=2)
Button(root,text=".",width=10,command=lambda:show(".")).grid(row=5,column=2)
Button(root,text="=",width=10,bg="yellow",command=lambda:calculate()).grid(row=5,column=3)
root.mainloop()
#---------------------------------选项按钮与复选框-----------------------------------
"""
选项按钮:radiobutton(父对象,options,...),只能勾选一个选项,大部分参数一样,下面列取特殊的:
1.indicatoron:当此值为0时,可以建立盒子选项按钮。
2.textvariable:可以以变量方式显示选项按钮
3.variable;设置或取得目前选取的单选按钮,值类型一般为IntVar、StringVar。
4.value:选项的值,也相当于variable的值。(get()和set()可以获取和修改这个值)
"""
def printselection():
print(cities[var.get()]) # 打印获取到的选项内容
root = Tk()
root.title("选项按钮")
#如果选项较多可以用字典的型式,也可以一个一个创建radiobutton选项。
cities = {0:"东京",1:"纽约",2:"巴黎",3:"香港"}
var = IntVar() #将变量var值设定为数值型
var.set(0) #初始选项设为0
label = Label(root,text="选择你喜欢的城市",fg="blue",bg="lightyellow",width=30).pack()
# indicatoron设置为0表示盒子选项按钮,不设置或设置其他值为普通选项按钮。
# 当选上相应的选项,value的值会赋予给变量var,然后执行函数printselection.
for val, city in cities.items():
Radiobutton(root,text=city,indicatoron=0,width=30,variable=var,value=val,
command=printselection).pack()
root.mainloop()
"""
复选按钮:Checkbutton(父对象,options,...),可以勾选对歌选项,参数和选项按钮大致相同
ertry一些常用方法:
.select_range(0,END):选取全部字符串
.select_clear():取消选取
.delete:删除文字
"""
def printInfo():
selection = ""
for i in checkboxes:
if checkboxes[i].get() == True: # 被选项框选取后对应的选项为True,未选上为False
selection = selection + sports[i] + "\t"
print(selection)
root = Tk()
root.title("复选按钮")
Label(root,text="请选择喜欢的运动",fg="blue",bg="lightyellow",width=30).grid(row=0)
sports = {0:"美式足球",1:"棒球",2:"篮球",3:"网球"}
checkboxes = {} # 字典存放被选取的项目的状态(TRUE OR FALSE)
for i in range(len(sports)):
checkboxes[i] = BooleanVar() # checkboxes[i]值的类型为布尔型,勾选后反馈Ture
Checkbutton(root,text=sports[i],variable=checkboxes[i]).grid(row=i+1,sticky=W)
btn = Button(root,text="确定",width=10,command=printInfo)
btn.grid(row=i+1)
root.mainloop()
#------------------------------容器控件-----------------------------------------
"""
框架的概念:相当于一个容器控件,在设计复杂GUI时,可以将控件放在不同的框架内。
1.Frame(父对象,options,...):单纯生成框架,不含框架标签(文字)
2.LabelFrame(父对象,options,...):带标签的框架。
3.Toplevel(options,...):顶层窗口,生成一个新的窗口作为框架,不需要父对象,窗口属性部分参数法适用于它。
相关参数:(大致和上面一样)
1.width:框架宽度(或窗口宽度)
2.height:框架高度(或窗口高度)
3.labelAnchor:设置放置标签的位置。
4.relief:标签的外框样式(用得比较多)
# 一般创建框架,然后往框架内放置控件后,再进行包装和定位此框架。(frame可以省略父对象)
"""
def printInfo():
selection = ""
for i in checkboxes:
if checkboxes[i].get() == True: # 被选项框选取后对应的选项为True,未选上为False
selection = selection + sports[i] + "\t"
print(selection)
root = Tk()
root.title("复选按钮")
root.geometry('400x200')
labframe = LabelFrame(root,text="选择最喜欢的运动") #创建带标签框架
sports = {0:"美式足球",1:"棒球",2:"篮球",3:"网球"}
checkboxes = {} # 字典存放被选取的项目的状态(TRUE OR FALSE)
for i in range(len(sports)):
checkboxes[i] = BooleanVar() # checkboxes[i]值的类型为布尔型,勾选后反馈Ture
Checkbutton(labframe,text=sports[i],variable=checkboxes[i]).grid(row=i+1,sticky=W)
labframe.pack(ipadx=5,ipady=5,pady=10) # 框架内所有控件做好后再包装此框架(好像不一定)
btn = Button(root,text="确定",width=10,command=printInfo)
btn.pack()
root.mainloop()
#------------------------------尺度条scale、spinbox--------------------------------
"""
Scale():通过移动尺度条产生某一范围的数字,特有参数如下:
1.command:使用或者更改数值时,自动运行该函数
2.digits:尺度数值,读取时需要用那个IntVar、Double、StringVar变量类型来读取
3.from_:尺度条范围值的初值。
4.to:尺度条范围值的末端值。
5.label:默认是没有标签的,赋予后水平尺度条标签在左上角,垂直在右上角。
6.length:默认100像素。
7.orient:尺度条默认是垂直,水平设置为HORIZONTAL
8.resolution:每次更改的数值,就是步长
9.tickinterval:尺度条的标记刻度。
10.troughcloro:滚动槽颜色
11.cariable:设置或取得目前选取的尺度值,类型通常为IntVar或StringVar(感觉和2配合)
12.width:对于垂直就是宽度,对于水平则是高度。
xx=askcolor():该方法调出色彩框选取色彩,返回一个元组,第一个元素为3个RGB,第二个元素为16进制色彩
"""
# 滚动设置窗口背景颜色示例:
def bgupdate(source):
"""更改窗口背景颜色"""
red = rSlider.get() # 读取red的值(这里和上面不太一样,直接get()控件的对象)
green = gSlider.get()
bule = bSlider.get()
print("R=%d,G=%d,B=%d" % (red, green, bule)) # 打印获取的颜色RGB
myColor = "#%02x%02x%02x" % (red, green, bule) # 将颜色转化为16进制字符串
root.config(bg=myColor) #设置窗口颜色
root = Tk()
root.title("更改背景窗口颜色")
root.geometry("360x240")
fm = Frame(root)
fm.pack()
rSlider = Scale(fm, from_=0, to=255, command=bgupdate) #设置scale控件在框架内,范围值和函数
gSlider = Scale(fm, from_=0, to=255, command=bgupdate)
bSlider = Scale(fm, from_=0, to=255, command=bgupdate)
gSlider.set(125) #设置初始值
rSlider.grid(row=0,column=0)
gSlider.grid(row=0,column=1)
bSlider.grid(row=0,column=2)
root.mainloop()
"""
Spinbox():另一种输入控件,类始于Entry和Button的合体,可以用鼠标单击UP/DOWN来选择上下数值。:
1.format:格式化字符串
2.from_ / to : 数值的初始值和末端值
3.increment:每次单击UP/DOWM按钮的增值或者减值(步长)
4.repeatdelay:设置长安按钮数值变化的时间间隔,默认300ms
5.textvariable:设置一边凉方式显示
6.values:可以是元组或者其他序列值(给定数列值,按UP/DOWM来显示该数列,可以是字符串)
7.width:对于垂直就是宽度,对于水平则是高度。
8.wrap:单击UP/DOWM按钮可以重新开始
9.xscrollcommand:在x轴使用滚动条
"""
def printInfo():
print(sp.get())
root = Tk()
root.title("Spinbox控件")
cities = ("新加波", "上海", "东京")
sp = Spinbox(root, values=cities, command=printInfo) # 将cities作为UP/DOWN选项
# 也可以做成显示数值:
# sp = Spinbox(root, from_=0, to=10 , command=printInfo)
sp.pack(pady=10,padx=10)
root.mainloop()
#--------------------------------message 和 messagebox------------------------------------
"""
message():具体用法和Label差不多,方法也一致
messagebox():相当于弹出一个对话框,主要包含8种:
1.showinfo(title,message,options):显示一般消息。
2.showwarning(title,message,options):显示告警消息。
3.showwerror(title,message,options):显示错误消息。
4.askquestion(title,message,options):显示询问消息,若单击“是”按钮会传回“yes”,“否”按钮传回“no”。
5.askquestion(title,message,options):显示确定或取消消息,单击“确定”按钮传回“True”,"取消"传回“False”。
6.askquestion(title,message,options):显示是或否消息,单击“是”传回“True”,“否”传回“False”。
7.askquestion(title,message,options):显示是或否或取消,分别传回True、False、None。
8.askquestion(title,message,options):显示重试或取消,分布传回True、False。
上面对话框内参数基本相同,titles是对话框名称,message为内容,options为可选参数,可选主要有3个:
1.default constant:默认按钮是OK(确认),YES(是),Retry(重试),也可以更改此设定
2.icon(constant):可设置所显示的图标,有INFO、ERROR、QUESTION、WARNING 4种
3.parent(wedget):指出当对话框关闭时,焦点窗口将返回此父窗口。
!!最后注意,因为对话框是放在tkinter模块内的messagebox模块下,所以要使用这些默认对话框需要
在程序开头增加导入 from tkinter import messagebox
"""
from tkinter import messagebox
def myMsg1():
ret = messagebox.askretrycancel("test1","安装失败,再试一次")
print("安装失败",ret) #ret 为回传消息,根据这个回传值可以进行更多判定和执行方式
def myMsg2():
ret = messagebox.askyesnocancel("test2","编辑完成,是或否或取消")
print("编辑完成",ret)
root = Tk()
root.title("messagebox")
root.geometry("360x240")
Button(root, text="安装失败", command=myMsg1).pack()
Button(root, text="编辑完成", command=myMsg2).pack()
root.mainloop()
#-------------------------------------事件和绑定-----------------------------------------
# tkinter最后一个指令.mainloop()就是让程序进入时间等待循环。
"""
widget提供为事件的绑定处理机制语法如下:widget.bind(event,handler);其中widget是事件的来源,
可以是root窗口,或者任意widget控件等,event为触发的事件如:鼠标单击,键盘等,handler为事件
处理程序,相当于当event时间本触发时,运行相关的程序或函数。
列取相关鼠标事件:
<Button-1>:单击鼠标左键,鼠标光标相对空间位置会被存入时间对象的x和y变量。
<Button-2>:单击鼠标中键,鼠标光标。。。。。。。
<Button-3>:单击鼠标右键,。。。。。。。。
<Button-4>:鼠标滑轮向上滚动,。。。。。。。
<Button-5>:鼠标滑轮向下滚动,。。。。。。。
<Mition>:鼠标移动,。。。。。。
<B1-Motion>:拖拽,按住鼠标左键再移动,。。。。。。
<B2-Motion>:拖拽,按住鼠标中键再移动,。。。。。。
<B3-Motion>:拖拽,按住鼠标右键再移动,。。。。。。
<ButtinRelease-1>:放开鼠标左键,。。。。。。
<ButtinRelease-2>:放开鼠标中键,。。。。。。
<ButtinRelease-3>:放开鼠标游右键,。。。。。。
<Double-Button-1>:双击左键,。。。。。。
<Double-Button-2>:双击中建,。。。。。。
<Double-Button-3>:双击右键,。。。。。。
<Enter>:鼠标进入wiget控件
<Leave>:鼠标离开wiget控件
键盘事件:
<FocushIn>:键盘焦点进入widget控件
<FocusOut>:键盘焦点离开wiget控件
<Return>:按下Enter键,键盘上所有的键都可以本绑定。
<Key>:按下某键盘键,键值会被储存在event对象中传递
<Shift-Up>:按住Shift同时按下Up
<Alt-Up>:按住Alt同时按下Up
<Ctrl-Up>:按住Ctrl同时按下Up
控件事件:
<Configure>:更改Widet控件的大小和位置,新的控件大小的width与height会储存在event对象内
"""
def enter(event): # !!必须要有参数event,因为事件会传递对象给此事件处理程序
x.set("鼠标进入Exit功能按钮")
def leave(event):
x.set("鼠标离开Exit功能按钮")
def myMsg(event):
print("YYYYY")
ret = messagebox.askretrycancel("test1","确定要退出吗?")
root= Tk()
root.title("鼠标事件绑定")
root.geometry("300x180")
btn = Button(root,text="Exit",command=root.destroy) # 这里最后没有退出。
btn.pack(pady=20)
btn.bind("<Enter>",enter) #鼠标进入EXIT区域自动触发Enter事件,从而触发处理程序entry()
btn.bind("<Leave>",leave)
btn.bind("<Button-1>",myMsg,add="+") #如果要一个事件触多个处理程序,需要加入参数add="+"
# 程序会先执行bind() 绑定的程序,然后再执行button内command指定的程序
x = StringVar()
lab = Label(root,textvariable=x,bg="yellow",height=4,width=15,font=("times 12 bold"))
lab.pack(pady=30)
root.mainloop()
# 在框架内的键盘事件绑定需要先获取焦点,一般鼠标先点击框架区域才能获取键盘焦点
# 取消绑定:obj.unbind("<xxx>")
# 窗口管理程序:触发事件"WM_DELETE_WINDOW"可以用messagebox来绑定处理关闭窗口的事件例如:。
# root.protocol("WM_DELETE_WINDOW",callback) 用.protocol()方法来添加这类型控件
def callback():
res = messagebox.askretrycancel("OKCANCEL","结束或取消")
if res ==True:
root.destroy()
else:
return
#----------------------------------列表框Listbox和滚动条Scrollbar---------------------------
"""
Listbox(): 列表框,可以设置单选多选,大部分参数通用:
1.highlightcolor:当列表框获得焦点时的颜色
2.listvariable:以变量方式处理选项内容
3.selectbackground:被选去字符串的背景颜色
4.selectmode:可以决定有多少选项可以被选,以及鼠标拖拽如何影响选项。
1.BROWSE:这是默认值,可以选择一个选项,如果选取一个选项同时拖拽鼠标,将造成选项
最后的位置是被选取的项目位置。
2.SINGLE:只能选择一个选项,可以用单击方式选取,不可以用拖拽方式更改所选的项目。
3.MULTIPE:可以选择多个选项,单击项目可以切换是否选择该项目
4.EXTENDED:单击第一个项目然后拖拽到最后一个项目,即可选择这个区间的一些列选项,
单击可以选择一个项目,此时若是按住shift键兵单击另一个项目,可以选择区间。
5.xscrollcommand:在x轴使用滚动条。
6.yscrollcommand:在y轴使用滚动条。
# 建立列表框后可以用 insert(index,elements)方法为列表框建立插入项目,index是位置,最后可以用END,
elements是插入项,可以是列表变量,或者单个字符串和以逗号分隔的多个字符串
如果将END改为ACTIVE,表示是在目前被选选项前面加入一个项目,如果尚未选择此项,ACTIVE是0就是最前面
lb.insert(ACTIVE,"orange","grapes","mango"):在前面补充建立三个项目
Listbox的基本操作方法:
1.size():传回列表项目的数量, lb.size(),列出选项总的数量
2.selection_set():选取特定索引项,例:lb.selection_set(0)表示默认选取第0个选项,(0,3)表示选取0~3
3.delete:删除特定索引项 lb.delete(1,3),表示删除1~3索引的项
4.get():传回指定索引项 lb.get(1,3),表示传回1~3索引的项名称,以元组的方式传回
5.curselection():传回选取项目的索引 a=lb.curselection()返回所选取项的索引
6.selection_include:检查指定索引项是否被选取 lb.selection_include(1)检查索引1是否被选,否False
"""
#Listbox 与事件绑定,当Listbox选取操作会产生<<ListboxSelect>>虚拟事件:
def itemAdded(): # 增加项目处理程序
VarAdd = entry.get()
if (len(VarAdd.strip()) == 0): # 没有增加不处理
return
lb.insert(END,VarAdd) # 将Entry中的项加在列表框最后
entry.delete(0,END) # 添加完成后删除文本框内数据
# 新增的打印所以只能一个个删
def itemDelted():
index = lb.curselection() # 传回被选取项的索引
if(len(index) == 0):
return
lb.delete(index) # 删除索引对应的项
def itemsSelected(event): # 将被选取项 打印到shell上
obj = event.widget # 获取事件对应的对象(就是获取事件发生的widget)
indexs = obj.curselection()
for index in indexs:
print(obj.get(index)) #打印所选取索引对应的项
print("------------")
root = Tk()
root.title("增加删除选项&虚拟绑定应用于多选")
entry = Entry(root)
entry.grid(row=0,column=0,padx=5,pady=5)
btnAdd = Button(root,text="增加",width=10,command=itemAdded)
btnAdd.grid(row=0,column=1,padx=5,pady=5)
lb = Listbox(root,selectmode=EXTENDED) # EXTENDED模式可以多选,拖拽
lb.insert(ACTIVE,"Banana","Watermelon","Pineappel","Orange","Grapes") #插入初始
lb.bind("<<ListboxSelect>>",itemsSelected) # 绑定虚拟事件,选定项目时执行函数
lb.grid(row=1,column=0,columnspan=2,padx=5,sticky=W) #columnspan合并2个单元格
btnDel = Button(root,text="删除",width=10,command=itemDelted)
btnDel.grid(row=2,column=0,padx=5,pady=5,sticky=W)
root.mainloop()
# 滚动条设计:
"""
Scrollbar(父对象,options,...),Scrollbar控件除了可以应用在Listbox上也可以应用在Text和
Cancas控件上,下面是比较重要的参数:
1.jump:每次短距离的拖拽滚动条时都会触发command方法,默认是0,如果是1则放开鼠标才触发command
2.orient:可以设置HORIZONTAL/VERTICAL 分别是水平/垂直,默认为垂直。
3.command:滚动条移动时所触发的方法
滚动条应该算是一个独立的控件,用其他控件的yscrollcommand参数来做连动
"""
root = Tk()
root.title("滚动条")
scrollbar = Scrollbar(root)
scrollbar.pack(side=RIGHT,fill=Y)
# 创建Listbox,yscrollcommand 指向Scrollbar,set方法
# yscrollcommand=scrollbar.set表示将listbox与滚动条做连动
lb = Listbox(root,yscrollcommand=scrollbar.set)
for i in range(50):
lb.insert(END,"Line" + str(i))
lb.pack(side=LEFT,fill=BOTH,expand=True)
scrollbar.config(command=lb.yview) # 执行lb的yview()方法
root.mainloop()
#----------------------下拉式列表OptionMenu和Combobox---------------------------
# OptionsMenu(父对象,options,*values),其中*values是下拉列表,可以用元组的方式,也可以用","号分隔
def printSelection():
print("The selection is : ",Var.get()) # 获取选项变量值
root = Tk()
root.title("OptionsMenu")
root.geometry("300x180")
omTuple = ("python","Java","C")
Var = StringVar(root) # 留意此处root,不懂,试了下没有root照样运行
Var.set("python") # 设定默认选项,也可以Var.set(OmTuple[0])
optionmenu = OptionMenu(root,Var,*omTuple) # 用元组作为下拉菜单导入给
optionmenu.pack(pady=10)
btn = Button(root,text="print",command=printSelection)
btn.pack(pady=10,anchor=S,side=BOTTOM)
root.mainloop()
"""
组合框Combobox(父对象,options):这是tkinter.tkk的widgeton控件,常用options参数:
1.textvariable:可以设置Combobox的变量值。
2.value:Combobox的选项内容,内容以元组方式存在。
设置默认选项可以用.current()方法,当然也可以用set()
当Combobox选项有变动时,会产生虚拟<<ComboboxSelect>>事件,也可以用这个特性绑定处理方法
"""
from tkinter.ttk import *
def commboxSelection(event):
labelVar.set(var.get())
root = Tk()
root.title("Combobox")
root.geometry("300x180")
var = StringVar()
cb = Combobox(root,textvariable=var)# 把cb对象以变量的形式赋予给var(后面可以直接var.get())
cb["value"] = ("python","Java","C","C#") # 可以通过这种方式赋予列表,也可以直接在Combobox内
cb.current(0) # 设定默认选项
cb.bind("<<ComboboxSelected>>",commboxSelection) # 绑定虚拟事件运行的程序
cb.pack(side=LEFT,padx=10,pady=10)
labelVar = StringVar()
label = Label(root,textvariable=labelVar) # 将label被选项的值赋予给labelvar变量
labelVar.set(var.get())
label.pack(side=LEFT)
root.mainloop()
#--------------------------------容器PanedWindow和Notebook----------------------------
"""
PanedWindow:相当于面板是一个widget容器,和Frame框架不一样,建立在PanedWindow内的控件不需要再包装
但建立在Frame内的控件需要包装,可以在PanedWindow内建立框架在建立控件,常用参数:
1.orient:面板配置的方向默认是水平HORIZONTAL,VERTICAL
2.width:面板整体宽度,没有默认值
add(child,options):用插入子控件来往容器内插入控件对象,child为插入的控件对象,可用用参数weight
weight:变化比例,表示拉伸窗口是每个容器的变化比,这个是tkk模块,必须先导入,1为比率为1:1
"""
from tkinter.ttk import * # 因为使用了weight。
root = Tk()
root.title("容器PanedWindow")
pw = PanedWindow(orient=HORIZONTAL) # 创建PanedWindow对象
leftframe = LabelFrame(pw,text="left pane",width=120,height=150) # 框架父对象是pw容器
pw.add(leftframe,weight=2) # 往容器内插入框架控件
middleframe = LabelFrame(pw,text="middle pane",width=120)
pw.add(middleframe,weight=2)
rightframe = LabelFrame(pw,text="right pane",width=120) # 这里pw父对象可以省略,因为下面add加入
pw.add(rightframe,weight=1) # 拉伸时比例为1
pw.pack(fill=BOTH,expand=True,padx=10,pady=10)
root.mainloop()
# 也可以往PanedWindow容器内插入其他控件,如label、entry等。
"""
Notebook:也是一个Widget容器控件,这个控件的特点是拥有许多选项卡,相当与子窗口(Notebook是ttk)
创建Notebook容器控件后,通过add(子对象,options)方法加入子选项卡,option参数如下:
1.compound:可以设置选项卡内同时含有图像和文字时彼此的关系
2.padding:可以设置Notebook和面板pane的额外控件
3.image:选项卡以图像方式呈现
4.state:可能值是normal、disabled、hidden,表示正常,无法被选取和隐藏
5.sticky:指出窗口面板的配置方式,n/s/e/w,表示方向
6.text:选项卡的名称
"""
from tkinter.ttk import *
from tkinter import messagebox
def msg():
messagebox.showinfo("Notebook","欢迎使用Notebook")
root = Tk()
root.title("容器Notebook")
root.geometry("300x160")
notebook = Notebook(root)
frame1 = Frame()
frame2 = Frame() #省略父对象,因为当整个框架做完后,会通过add加入到notebook容器内。
label = Label(frame1,text="Python")
label.pack(padx=10,pady=10)
btn = Button(frame2,text="help",command=msg)
btn.pack(padx=10,pady=10)
# 将框架控件插入到容器内
notebook.add(frame1,text="页次1")
notebook.add(frame2,text="页次2")
notebook.pack(padx=10,pady=10,fill=BOTH,expand=TRUE)
root.mainloop()
#--------------------------------进度条 Progressbar-------------------------
"""
Progressbar():进度条,是tkinter.ttk模块,常用参数:
1.length:进度条的长度,默认为100像素
2.mode:可以有下列两种模式:
(1)determinate:默认模式,一个指针从起点到终点。
(2)indeterminate:一个指针在起点和重点来回移动。
3.maximum:进度条的最大值,默认是100
4.name:进度条名称,供程序参考引用
5.orient:进度条的方向,可以是HORIZONTAL(默认),或VERTICAL
5.value:进度条当前值
6.variable:记录进度条目前的进度值
Progressbar的方法:
value用update()方法更新值,以达到动画效果
1.start(interval):每隔interval时间移动一次指针,默认值是50ms
2.step(delta):在step()方法内的delta参数的意义是增量值,每次增加一次delta,默认值是1
3.stop:停止start()的运行
"""
from tkinter.ttk import *
import time
def run():
pb.start()
def stop():
pb.stop()
# 这个函数的作用每隔0.05秒进度条增加2,并打印当前值,满后重新开始。
def running():
while pb.cget("value")<= pb["maximum"]: # 当前值小于最大值时不断循环
pb.step(2) # 递增值为2
root.update() # 更新当前值(就是增加2后)
print(pb.cget("value")) # 打印出当前值
time.sleep(0.05) # 每隔0.05秒循环一次
root = Tk()
root.title("进度条 Progressbar")
# 设置进度条长度、模式和方向
pb = Progressbar(root,length=200,mode="determinate",orient=HORIZONTAL)
pb.pack(padx=5,pady=10)
pb["maximum"] = 100 # 设置进度条最大值
pb["value"] = 0 # 设置进度条当前值(初始)
btnRun = Button(root,text="Run",command=run) # 可以替换为running试试
btnRun.pack(side=LEFT,padx=5,pady=10)
btnStop = Button(root,text="Stop",command=stop)
btnStop.pack(side=LEFT,padx=5,pady=10)
root.mainloop()
# -----------------------------------菜单栏 Menus------------------------
"""
Menu():下拉式菜单栏,常用参数:
tearoff:菜单上的虚线分隔线,当默认值为True或1时,菜单列表位置从1开始放置,同时点击虚线
可以让菜单分离出来单独的窗口,如果tearoff值为Fslse或0时,菜单列表由0开始,并且
此时不会显示虚线分隔线,菜单也无法分离出去。
相关方法:
add_cascade():建立分层菜单,同时让此子功能列表与父菜单建立连接。
add_command():增加菜单列表
add_separator():增加菜单列表分隔线(实线,子菜单列表过多时可用;方法直接作用在Menu上)
建立菜单列表时所用到的概念如下:
menubar = Menu(root) # 建立最上层菜单
filemenu = menu(menbar) # 在上层菜单的基础上建立菜单对象
menubar.add_cascade(label="File",menu=filemenu) # 在最上层菜单上添加分层菜单,并链接
建立子菜单:
findmenu = Menu(filemenu)
filemenu.add_cascade(label="Find",menu=findmenu) # 在分层菜单的基础上建立子菜单,并连接
ALT快捷键:就是某个菜单类别或列表指令的英文字符串内单一字母添加下划线,然后可以用ALT键先启动
此功能。设计方法是在下列两个方法内增加underline参数
1.add_cascade(....,underline=n)
2.add_command(....,underline=n) # n代表第几个索引字母含下划线
要实现右击出现菜单可以在menu上绑定右击事件,然后在menu上使用.poss()方法调出菜单栏。P213
XXlabel.pack_forget()调用此方法可以隐藏次控件(可以用作事件处理函数)
在设计菜单列表是可以用add_checkbutton()创建复选框。
"""
# import 不重复了
# 创建子菜单列表事件
def findNext():
messagebox.showinfo("Find Next","查找下一个")
def findPre():
messagebox.showinfo("Find Pre","查找下一个")
#创建分层菜单列表事件
def newFile():
messagebox.showinfo("New File","新建文档")
def openFile():
messagebox.showinfo("Open File","打开文档")
def saveFile():
messagebox.showinfo("Save File","保存文档")
def saveAsFile():
messagebox.showinfo("Save As File","另存为")
def aboutMe():
messagebox.showinfo("About Me","XXXX")
# 创建右键菜单列表事件
def minmizeIcon():
root.iconify() # iconify方法的作用是缩小窗口为图标
def showPopupMenu(event):
popupmenu.post(event.x_root,event.y_root) # 在鼠标的点击的位置x,y处弹出菜单
# 创建菜单栏中的复选框事件
def status():
if demoStatus.get(): # 获取复选框是否被选上
statusLabel.pack(side=BOTTOM,fill=X) # 包装显示该控件
else:
statusLabel.pack_forget() #.pack_forget()隐藏此控件
# 窗口设计
root = Tk()
root.title("菜单_Menu")
root.geometry("300x180")
menubar = Menu(root)
filemenu = Menu(menubar,tearoff=False) # 将分层菜单建立在上层菜单上,不显示虚线分隔线
menubar.add_cascade(label="File",menu=filemenu,underline=0) # 在第0个字母加下划线
# 创建分层菜单下的子菜单
findmenu = Menu(filemenu,tearoff=False)
findmenu.add_command(label="Find Next",command=findNext) # 添加子菜单列表
findmenu.add_command(label="Find Pre",command=findPre)
filemenu.add_cascade(label="Find",menu=findmenu)
filemenu.add_command(label="New File",command=newFile,underline=0) #添加菜单列表
filemenu.add_command(label="Open File",command=openFile,underline=0)
filemenu.add_separator() # 创建实线分割线
filemenu.add_command(label="Save File",command=saveFile,underline=0)
filemenu.add_command(label="Save As File",command=saveAsFile,underline=5)
filemenu.add_separator()
filemenu.add_command(label="Exit",command=root.destroy,underline=0)
helpmenu = Menu(menubar) # 这里保留虚线分隔线
menubar.add_cascade(label="Help",menu=helpmenu,underline=0) # underline拥有ALT快捷键
helpmenu.add_command(label="About Me",command=aboutMe,underline=0)
# 设计鼠标右击弹出菜单
popupmenu = Menu(root,tearoff=False)
popupmenu.add_command(label="Minimize",command=minmizeIcon) # 添加右击菜单列表
popupmenu.add_command(label="Exit",command=root.destroy)
root.bind("<Button-3>",showPopupMenu) # 绑定右击事件
# 设计菜单栏中的复选框
viewmenu = Menu(menubar,tearoff=False)
menubar.add_cascade(label="View",menu=viewmenu)
demoStatus = BooleanVar()
demoStatus.set(True)
viewmenu.add_checkbutton(label="Status",command=status,variable=demoStatus)
# 复选框中决定显示与隐藏的Label:
statusVar = StringVar()
statusVar.set("显示")
statusLabel = Label(root,textvariable=statusVar,relief="raised")
statusLabel.pack(side=BOTTOM,fill=X)
root.config(menu=menubar) # 显示菜单栏对象,!!!不能漏了
root.mainloop()
#----------------------------------文字区域 Text-------------------------------
"""
Text(): 是一个文字区域控件,可以处理多行输入或镶嵌图像等编辑功能(相当于一个文本),常用参数:
1.exportselection:如果执行选择操作时,所选字符串会自动输出至剪切板,想避免设置值为0.
2.height/width:文字区域中的高度和宽度,单位是字符高和字符宽
3.padx/pady:text左右上下框与与文字各个方向的间距
4.relief:默认是relief=SUNKEN,文字外框样式。
5.state:输入状态:NORMAL / DISABLED
6.wrap:可以控制某行文字太长时的处理,默认是wrap=CHAR(??)
7.xscrollcommand:在x轴使用滚动条
8.yscrollcommand:在y轴使用滚动条(使用方法,yscrollcommand=滚动条对象)
字形FONT()方法:这里只填常用的3个参数 family字形,weight是否粗体,size大小
f=Font(family=xx,weight=nomal,size=xx);text.configure(font=f)
属于tkinter.font模块需要from tkinter.font import Font
Text的方法:
insert(index,string): 将文字插入指定的索引位置,另外第三个参数可以将插入文字添加为标签tag
get(startindex,endindex):获取text内容:get(SEL_FIRST,SEL_LAST)可以获取当前Text被选取的值
get(1.0,END):获取全部值
text.delete(startindex,endindex):删除指定索引字段
Text的索引:(行.列:1.2表示1行第2列)
text.index(INSERT):目前插入点的位置(即光标所在坐标或索引)
text.index(CURRENT):和上面意思差不多,表示广播目前相对于字符串的位置
text.index(END):最后一个字符串的位置
text.index(SEL_FIRST):被选取文字的开始索引,SEL_LAST为结束索引
添加滚动条:
需要在创建Text和Scrobar都需要互相指定:(1)yscrollbar.config(command=text.yview)
(2)text.config.(yscrollocommadn=yscrollbar.set)
另外在tkinter.scrolledtext模块内有ScrolledT ext控件可以创建默认含有滚动条的控件:
(1)from tkinter.scrolledtext import ScrolledText
(2)text = ScrolledText(root,undo=true)
建立书签(Marks)和标签(tag):
在文件特殊的位置建立书签,而标签tag是值一个区域文字
mark_names():传回这个Text对象的所有书签
index(mark):传回指定书签的line和column(索引)
mark_set(mark,index):在指定的index位置设置书签
mark_unset(mark):取消指定书签设置
tag_add(tagname,startindex[,endindex]...):将startindex到endindex之间的文字命名为tagname的标签
tag_config(tagname,options,..):编辑绑定标签,一般label参数差不多,wrap可使用模式NONE,CHAR,WORD
tag_delete(tagname):删除此标签,同时移除此标签特殊的编辑或绑定
tag_remove(tagname,startindex[,endindex]...):删除标签,但不删除标签定义和标签特殊的编辑或绑定
text.tag_config(SEL,options):除了tag_add()自定义标签外,系统还有一个内建的SEL,表示所选取的区间
也可以在insert()的第三个参数增加标签"a",然后再text.tag_config("a",options)
通过书签创建标签:
text.mark_set("mark1",5.0)
text.mark_set("mark1",8.0)
text.tag_add("tag1,"mark1","mark1")
text.tag_config("tag1",foreground="blue",background="lightyellow")
Cut/Copy/Paste 功能:上述三个功能已经内奸为tkinter的虚拟事件可以直接引用:
text.event_geberate("<<Cut>>") text.event_geberate("<<Copy>>") text.event_geberate("<<Paset>>")
复原undo和重做redo:Text默认没有开启,开始需要在Text方法内增加undo=True:
Text.edit_undo() (复原,相当于返回上一步)
Text.edit_redo() (恢复最原始状态)
查找文字 search()方法: pos = text.search(key,startindex,endindex) pos传回找到的字符串的索引位置
key表示需要查找的字符串,startindex和endindex表示查找的起始和终止区域
调出文档保存和打开文档窗口: tkinter.filedialog中的模块asksaveasfilename和askopenfilename
filename = asksaveasfilename():启动另存为对话框,保存后传回文档的路径,输入参数
asksaveasfilename(defaultextension=".text")设置默认后缀
filename = askopenfilename():启动打开文件对话框,打开后传回文档的路径
text.focus_set表示这个text对象获取焦点
"""
from tkinter.font import Font
from tkinter.ttk import *
def sizeSelected(event):
f=Font(size=sizeVar.get())
text.tag_config(SEL,font=f) # SEL系统内建标签,表示所选区域
# 右击菜单运行程序
def cutJob():
text.event_generate("<<Cut>>")
def copyJob():
text.event_generate("<<Copy>>")
def pasteJob():
text.event_generate("<<Paste>>")
def showPopupMenu(event):
popupmenu.post(event.x_root,event.y_root)
root = Tk()
root.title("TEXT文字区域")
root.geometry("300x180")
# 建立右击菜单
popupmenu = Menu(root,tearoff=False)
popupmenu.add_command(label="Cut",command=cutJob)
popupmenu.add_command(label="Copy",command=copyJob)
popupmenu.add_command(label="Paste",command=pasteJob)
root.bind("<Button-3>",showPopupMenu)
# 建立工具栏
toolbar = Frame(root,relief=RAISED,borderwidth=1)
toolbar.pack(side=TOP,fill=X,padx=2,pady=1)
# 建立font size combobox
sizeVar = IntVar()
size = Combobox(toolbar,textvariable=sizeVar)
sizeFamily = [x for x in range(8,30)] # 字体大小
size["value"] = sizeFamily
size.current(4) # 默认选取索引4,就是12
size.bind("<<ComboboxSelected>>",sizeSelected)
size.pack()
# 建立TEXT
text = Text(root)
text.pack(fill=BOTH,expand=True,padx=3,pady=2)
text.insert(END,"Five Hundred Miles\n","aaa") # 输入第3参数,将该段作为标签(此处无意义)
text.insert(END,"If you miss the rain I'm on\n")
text.insert(END,"You will know that I am gone.\n")
text.insert(END,"You can hear the whistle blow\n")
text.insert(END,"A hundred miles,\n")
text.focus_set() # focus_set表示这个对象获取焦点
root.mainloop()
# 程序:查找文字
def mySearch():
text.tag_remove("found","1.0",END) # 每一次查询前清除前一次标签(删除标签但不删除标签定义)
start = "1.0" # 设置起始位置
key = entry.get() # 读取查找关键词
if (len(key.strip()) == 0):
return
while True:
pos = text.search(key,start,END)
if (pos == ""):
break
text.tag_add("found",pos,"%s+%dc" % (pos,len(key)))
start = "%s+%dc" % (pos,len(key)) # 更新查找起始位置,从新的起始位置接着再查找
root = Tk()
root.title("查找文字")
root.geometry("300x180")
root.rowconfigure(1,weight=1)
root.columnconfigure(0,weight=1) # 拉伸缩放比例
entry = Entry()
entry.grid(row=0,column=0,padx=5,sticky=W+E)
btn = Button(root,text="查找",command=mySearch)
btn.grid(row=0,column=1,padx=5,pady=5)
text = Text(root,undo=True)
text.grid(row=1,column=0,columnspan=2,padx=3,pady=5,sticky=N+S+W+E)
text.insert(END,"Five Hundred Miles\n")
text.insert(END,"If you miss the rain I'm on\n")
text.insert(END,"You will know that I am gone.\n")
text.insert(END,"You can hear the whistle blow\n")
text.insert(END,"A hundred miles,\n")
text.tag_config("found",background="yellow") # 定义找到的标签
root.mainloop()
# 程序打开保存文档
from tkinter.filedialog import asksaveasfilename
from tkinter.filedialog import askopenfilename
# 设计菜单栏3个功能函数
def newFile():
text.delete("1.0",END) # 删除Text控件内容
root.title("Untitled") # 新建文件交后修改窗口名
def openFile():
global filename
filename = askopenfilename() # 掉出打开文件窗口,读取打开的文档名地址
if filename == "":
return
with open(filename,"r") as fileObj:
content = fileObj.read()
text.delete("1.0",END)
text.insert(END,content)
root.title(filename)
def saveAsFile():
global filename
textContent = text.get("1.0",END)
filename = asksaveasfilename(defaultextension=".txt") # 开启另存为对话框
if filename == "":
return
with open(filename,"w") as output:
output.write(textContent)
root.title(filename)
filename="Untitled"
root = Tk()
root.title(filename)
root.geometry("300x180")
menubar = Menu(root)
filemenu = Menu(menubar,tearoff=False)
menubar.add_cascade(label="File",menu=filemenu)
filemenu.add_command(label="New File",command=newFile)
filemenu.add_command(label="Open File",command=openFile)
filemenu.add_command(label="Save AS File",command=saveAsFile)
filemenu.add_separator()
filemenu.add_command(label="Exit",command=root.destroy)
root.config(menu=menubar) # 显示菜单对象
text = Text(root,undo=True)
text.pack(fill=BOTH,expand=True)
root.mainloop()
#--------------------------------Treeview 树状表格数据------------------------------
"""
Treeview():一种表格视图结构的控件,控件最左列为图标栏,右侧为一般栏,是tkinter.tkk的控件;参数:
1.columns:栏位的字符串,其中第一个为图标栏是默认的,不需要设置;赋予的值为一般栏
2.displaycolumns:设置栏位显示顺序。
3.height:控件每行高度
4.padding:设置内容与控件框的间距,规则P254
5.sekectmode:用户可以使用鼠标选择项目的方式:
1.selectmode=BROWSE,一次选择一项,这是默认的
2.selectmode=EXTENDED,一次可以选择多项
3.selectmode=NONE,无法用鼠标执行选择
6.show:默认是设置显示图标栏标签show="tree",如果省略隐藏图标栏则设置show="heading"
tree_obj.heading(#x,text="xxxx"):用来建立栏标题,其中x为栏标题的col数或栏位字符串,xxxx为栏标题的名称
一般用Treeview()创建栏位和控件,再用heaing()创建栏标题,最后用insert()插入栏内容。
insert("",index=END,text="aaa",values="bbb"):按顺序插入数据,其中第一个参数""为父id,层级式Treeview
时用来绑定父id,text为图标栏内容,values为一般栏内容,按从左到右的顺序(values可以用元组列表)
column(id,options):用于格式化Treeview栏位,id为#index的索引或栏位字符串,options参数:
1.anchor:可以设置栏内容参考位置,CENTER为居中
2.minwidth:最小栏宽,默认为20像素
3.stretch:默认是1,当控件大小改变时,栏宽随着改变的幅度
4.width:默认栏宽是200像素
可以使用:ret = column(id)不含参数,将会以字典的方式传回特定栏所有参数内容
tag_configure("tagName",option):此方法可以建立标签,然后定义此标签的格式:
1.background:标签背景颜色
2.font:字形设置
3.forground:标签前景颜色
4.image:图像与列表同时显示。
创建标签后,需要在插入数据时,将插入行绑定已经创建的标签:insert(····,tags="tagName")
层级Treeview:1.要在图标栏先建立top_level的项目id:idxx=tree.insert("",index=END,text="XXX")
2.再将相关子项目放在所属的top_level项目id:tree.insert("idxx",index=END,·······)
Style().configure("Treeview",rowheight=xx):添加图像时增加row高度
selection选项事件:鼠标选择时会触发虚拟事件<<TreeviewSelect>>,然后通过对Treeview控件使用
selection()方法获取其目前所选项目iid(iid是tiknter内部使用的id),获取类型为元组
delete(id):作用在Treeview控件内,删除对应的项目,参数为所删除项目的id(selection方法选取后需要遍历)
identify("xxx",event.x,event.y):"xxx"可以是item、column、row,使用双击时获取坐标和item、column或row信息,
"""
from tkinter.ttk import *
root = Tk()
root.title("层级Treeview")
asia = {"中国":"北京","日本":"东京","泰国":"曼谷","韩国":"首尔"}
euro = {"英国":"伦敦","法国":"巴黎","德国":"柏林","挪威":"奥斯陆"}
# 建立Treeview,选择模式为多选
tree = Treeview(root,columns=("capital"),selectmode=EXTENDED)
# 建立栏标题
tree.heading("#0",text="国家")
tree.heading("capital",text="首都")
# 建立top—level项目id
idAsia = tree.insert("",index=END,text="Asia")
idEuro = tree.insert("",index=END,text="Europe")
# 建立idAsia和idEuro底下内容
for country in asia.keys():
tree.insert(idAsia,index=END,text=country,values=asia[country])
for country in euro.keys():
tree.insert(idEuro,index=END,text=country,values=euro[country])
tree.column("capital",anchor=CENTER)
tree.pack(fill=BOTH,expand=True) # 拉伸时填满
root.mainloop()
# -----------------------------------------------------------------------
# 案例2:
from tkinter.ttk import *
from tkinter import messagebox
def removeItem(): # 删除所选的项目
ids = tree.selection() # 获取所选的项目
for id in ids:
tree.delete(id)
def insertItem(): # 插入项目
state = stateEntry.get() # 获取Entry输入的内容
city = cityEntry.get()
if (len(state.strip()) == 0 or len(city.strip()) == 0 ): #如果为空则跳过
return
tree.insert("",END,text=state,values=(city)) # 插入
stateEntry.delete(0,END) # 清空Entry
cityEntry.delete(0,END)
# 创建双击事件
def doubleClick(event):
e = event.widget # 获取触发事件控件,此处可以省略因,为已知是tree
iid = e.identify("item",event.x,event.y) # 获取双击项目id
state = e.item(iid,"text") # 取得state
city = e.item(iid,"values")[0] # 取得City
str = "{0}:{1}".format(state,city) # 格式化
messagebox.showinfo("Double Clicked",str) # 输出
# 建立点击选取时,下方出现所选项
def treeSelect(event):
itemselected = tree.selection()[0] # 获取所选项
col1 = tree.item(itemselected,"text") # 取得图标栏内容
col2 = tree.item(itemselected,"values")[0] # 取得第0索引栏位内容
str = "{0}:{1}".format(col1,col2)
var.set(str) # 设置状态栏内容
# 建立排序函数(不怎么懂)
reverseFlag = False # 排序标识著名是否反向排序
def treeview_sortColumn(col):
global reverseFlag # 定义排序表示为全局变量
#get_children([item])方法传回item的一个tuple的iid值,如果省略则得到一个tuple
lst = [(tree.set(st,col),st) for st in tree.get_children("")]
# print(lst)
lst.sort(reverse=reverseFlag) # 排序
# print(lst)
for index,item in enumerate(lst):
# move(iid,parent,index):将iid所指项目移至parent层次的index位置这里""表示panrent层次
tree.move(item[1],"",index)
reverseFlag = not reverseFlag
root = Tk()
root.title("Treeview案例2")
stateCity = {"伊利若":"芝加哥","加州":"洛杉矶","德州":"休斯敦","华盛顿州":"西雅图",
"江苏":"南京","山东":"青岛","广东":"广州","福建":"厦门","Mississippi":"Oxford",
"Kentucky":"Lexington","Florida":"Miama","Indiana":"West Lafeyette"}
# 设置窗口拉伸时缩放
root.rowconfigure(1,weight=1)
root.columnconfigure(1,weight=1)
root.columnconfigure(3,weight=1)
# 建立上层插入项目
stateLeb = Label(root,text="State:")
stateLeb.grid(row=0,column=0,padx=5,pady=3,sticky=W)
stateEntry = Entry()
stateEntry.grid(row=0,column=1,sticky=W+E,padx=5,pady=3)
cityLab = Label(root,text="City:")
cityLab.grid(row=0,column=3,sticky=E)
cityEntry = Entry()
cityEntry.grid(row=0,column=3,sticky=W+E,padx=5,pady=3)
# 建立Insert按钮
InBtn = Button(root,text="插入",command=insertItem)
InBtn.grid(row=0,column=4,padx=5,pady=3)
#建立Treeview
tree = Treeview(root,columns=("cities"),selectmode=EXTENDED) # 设置多选模式
tree.heading("#0",text="State")
tree.heading("cities",text="City")
tree.column("cities",anchor=CENTER)
tree.tag_configure("evenColor",background="lightblue") # 创建标签,颜色为浅蓝色
# 插入内容,双数行设置为标签(根据标签定义,颜色为浅蓝色)
rowCount = 1
for state in stateCity.keys():
if (rowCount % 2 == 1):
tree.insert("",index=END,text=state,values=stateCity[state])
else:
tree.insert("",index=END,text=state,values=stateCity[state],tags=("evenColor"))
rowCount += 1
tree.grid(row=1,column=0,columnspan=5,padx=3,sticky=W+E+N+S)
tree.bind("<Double-1>",doubleClick) # 绑定双击事件运行函数
tree.bind("<<TreeviewSelect>>",treeSelect) # 绑定选择虚拟事件运行函数
rmBtn = Button(root,text="删除",command=removeItem)
rmBtn.grid(row=2,column=2,padx=5,pady=3,sticky=W)
# 创建最底层的状态栏显示
var = StringVar()
label = Label(root,textvariable=var)
label.grid(row=3,column=0,sticky=W,columnspan=5)
# 创建滚动条
yscrollbar = Scrollbar(root)
yscrollbar.config(command=tree.yview) # 连接tree控件
tree.configure(yscrollcommand=yscrollbar.set) # tree控件绑定滚动条
yscrollbar.grid(row=1,column=5,sticky=N+S+W,padx=0) # 设置滚动条位置
# 单击标调栏将启动treeview_sortColumn函数排序(text为栏标题名,c为栏位名)
tree.heading("#1",text="City",command=lambda c="cities":treeview_sortColumn(c))
# 关于标题栏无法排序问题暂时不知道怎么解决,主要不知道标题栏c=""的名称是什么
# tree.heading("#0",text="state",command=lambda c="???":treeview_sortColumn(c))
root.mainloop()
推荐阅读
-
Python GUI Tkinter简单实现个性签名设计
-
Python Tkinter GUI编程入门介绍
-
Python中使用Tkinter模块创建GUI程序实例
-
Python入门笔记——程序设计的基础知识
-
[python学习笔记]Python语言程序设计(北理工 嵩天)
-
python库的tkinter带你进入GUI世界(计算器简单功能)
-
Python Tkinter GUI编程入门介绍
-
【笔记】嵩天-Python语言程序设计-完成两个简单实例
-
使用Python中tkinter库简单gui界面制作及打包成exe的操作方法(二)
-
python3.6 +tkinter GUI编程 实现界面化的文本处理工具(推荐)