文章1
文章2
一、
import tkinter as tk
app = tk.Tk() # 实例化对象,创建主窗口程序
app.title("FishC Demo") # 设置标题栏
theLable = tk.Label(app, text = "我的第二个窗口程序!")
#obj.Label(对象,文本) 可以显示文本、图像或图标
theLable.pack() #自动调节组件的位置、尺寸等
app.mainloop() # 窗口的主事件循环,显示窗口
import tkinter as tk
class APP():
# 通过构造函数设置参数
def __init__(self, master):
frame = tk.Frame(master) # 框架,将不同的类型分开
frame.pack(side = tk.LEFT, padx = 10, pady = 20) # 默认为 side=tkinter.TOP
self.hi_there = tk.Button(frame,text = "打招呼!", fg = "blue",command= self.say_hi)
# Button()是按钮组件
self.hi_there.pack()# 一个四个方位
def say_hi(self):
print("我小甲鱼来了!!")
root = tk.Tk() # 创建一个根窗口,把它作为参数
app = APP(root) # root窗口、实例化app对象
root.mainloop()
"""
obj.pack(side=...方式,padx x轴偏移位置, pady y轴偏移位置)
obj.Button(frame, 内容,bg背景颜色,fg字体颜色,按钮按下以后要显示的内容)
"""
Label组件: 插入图片与文字
文本obj = Label(root,text=‘内容’,justify=‘文字位置’,padx=,pady=,font=(‘字体’,字体大小)fg=‘前景颜色即字体颜色‘,bg=‘背景颜色’,width=宽度,height=高度)
文字与图片并存,使用PhotoImage()定义对象:
图片对象 = PhotoImage(file=‘图片路径且必为gif格式的图片’)
obj = Label(root,image=图片对象,text=‘内容’,compound=‘图片和文字的位置’)
obj.pack()
注意: compound可设置为:left 图像居左 right 图像居右 top图像居上 bottom 图像居下 center图像在文字下方
from tkinter import *
root = Tk()
textLabel = Label(root,
text="请勿观看,\n(此处可以换行)\n 否则........",
justify=LEFT,padx=10,fg='pink',bg='black')
textLabel.pack(side=LEFT) # 文字在左
photo = PhotoImage(file=r".\photo.gif") # ()中传入图片,图片支持GIF
imageLabel = Label(root,image=photo ) # image为图片对象
imageLabel.pack(side=RIGHT) # 图片在右
mainloop()
使用 pillow(PIL)模块打开JPG格式的图片(tkinter只支持GIF的)
注意:要 from PIL import Image,ImageTK
from tkinter import *
from PIL import Image,ImageTK # pillow 模块,这个方法是打开JPG图片,因为tkinter只支持GIF的
root = Tk()
photo_path = r".\photo2.JPG"
f = Image.open(photo_path)
tking = ImageTk.PhotoImage(f)
theLabel = Label(root,
text="欢迎来到 \n python学习区" ,
justify=LEFT,
image=tking,
compound=CENTER,
font=('行楷',25),
fg= "white"
) # CENTER表示图片在下,文字在正上方
# font = (字体,字体大小)
# fg = 字体颜色
theLabel.pack()
mainloop()
"""
Button : 接收文字信息
commond 指定函数或方法,用户点击后自动调用
"""
StringVar()和IntVar() :
>>>var_1 = StringVar()
>>>rad_2 = Radiobutton(root, text='conflict', variable = var_1, value="war").grid(row=0, column=2)
如果rad_2被点中var_1这个字符串变量里存了“war”
>>>check_var2 = IntVar()
>>>Ck_2 = Checkbutton(root, text = "Cat", variable = check_var2, onvalue = 1, offvalue = 0, height=6, width = 10).grid(row=1, column=0)
如果ck_2被选中check_var2里存入1,没选中存的是0
当按按钮时想让Label文本改变操作:
textvariable = 变化对象obj_change,如果想让同一个frame框架里的参数可变,就设置Label内textvariable参数
Label(frame框架,textvariable=var,...........),之后一定会有让var值改变的操作,比如Button()中设置参数command=自定义的函数 里面有var.set(XXX)
oby_change = StringVar() 设置字符串类型的可变参数
obj_change.set(设置文本str 第一次设置的是默认文本)
from tkinter import *
def callback():
var.set("吹吧你,我才不信呢")
root = Tk()
frame1 = Frame(root) # 构建框架1
frame2 = Frame(root) # 框架2
var = StringVar() # 设置tkinter的字符串变量,用StringVar获取对象
var.set("未满18岁请勿观看,\n(此处可以换行)\n 否则......") # obj.set(文字内容) 默认文本,有的会 obj.set(某数字)
textLabel = Label(frame1,
textvariable=var,
justify=LEFT
)# textvariable tkinter 的字符串变量,设置后可以改变文字内容
textLabel.pack(side=LEFT) # 文字在左
photo = PhotoImage(file=r".\best wishes.gif") # ()中传入图片,图片仅支持GIF
imageLabel = Label(frame1,image=photo ) # image为图片对象,放在frame1中
imageLabel.pack(side=RIGHT) # 图片在右
theButton = Button(frame2,text="我已满18周岁",command=callback)# 设置按钮、改变显示的文字内容 command 必须要,否则指令没用,有了command按下去后会自动调用command后的函数或者方法
theButton.pack() # 用框架2 pack显示文本内容
frame1.pack(padx=10, pady=10) # 设置水平、垂直距离,显示框架1"未满18岁请勿观看,\n(此处可以换行)\n 否则......"
frame2.pack(padx=10, pady=10) # 显示改变后的框架2
mainloop()
多选Checkbutton中的 variable参数:
obj = IntVar() 定义整形变量
variable=obj 指定变量来源
from tkinter import *
root = Tk()
v = IntVar() # 整形,存放checkbutton的选中状态
c = Checkbutton(root, text = "试试",variable=v)
c.pack()
l = Label(root,textvariable=v) # 默认值为0,选中为1
l.pack()
mainloop()
IntVar()用法:单选Radiobutton()中的variable参数
from tkinter import *
root = Tk()
root.title('new window')
v = IntVar()
for text,value in [('red',1),('yellow',2),('blue',3),('green',4)]:
r = Radiobutton(root, text=text, value=value, variable=v).pack(anchor=W)
v.set(2) # 设置默认值
root.mainloop()
多选Checkbutton 中IntVar():
案例中由于IntVar()默认值为0,所以variable直接从第一个开始索引
from tkinter import *
root = Tk()
Girls=['A','B','C','D','E']
v = [] # 每个人都需要一个列表来存放是否被选中 -1 未选中 0 选中
for girl in Girls:
v.append(IntVar()) # 给列表添加元素的方法 obj.append()
b = Checkbutton(root, text=girl, variable=v[-1]) # 每一次拿到最后一个元素,所以是-1
# 0和1有什么区别?0:一点全选,注意:variable=v[0]
b.pack(anchor=W) # anchor 显示方位
# anchor 表示对齐方式,左对齐”w”,右对齐”e”,顶对齐”n”,底对齐”s”,默认为center
mainloop()
单选Radiobutton 众多备选值共享一个variable参数,设置参数value 疑问:value干嘛的?????
from tkinter import *
root = Tk()
v = IntVar()
# 互测
Radiobutton(root,text="One",variable=v, value=1).pack(anchor=W)
Radiobutton(root,text="two",variable=v, value=2).pack(anchor=W)
Radiobutton(root,text="three",variable=v, value=3).pack(anchor=W)
mainloop()
单选Radiobutton 使用循环,设置 variable(只能共享一个) value
from tkinter import *
root = Tk()
LANGS = [
("python",1),
("Perl",2),
("Ruby",3),
("Lua",4)
]
v = IntVar()
v.set(1) # 设置默认选项,用obj.set(第几个的编号)
for lang,num in LANGS:
b = Radiobutton(root, text=lang, variable=v, value=num,indicatoron=False)
# 参数indicatoron = False 设置选项为方框形式 = True 为小圆按钮形式
b.pack(anchor=W)
mainloop()
LabelFrame() 让选项变得更好看:用法和frame一样,可以与选项组合使用
from tkinter import *
root = Tk()
group = LabelFrame(root, text="最好的脚本语言是:", padx=5, pady=5)
group.pack(padx=10, pady=10)
LANGS = [
("python",1),
("Perl",2),
("Ruby",3)
]
v = IntVar()
for lang,num in LANGS:
b = Radiobutton(group, text=lang, variable=v, value=num) # indicatoron = False设置选项的图标
b.pack(anchor=W)
mainloop()
二、
文本obj = Entry(root)
操作: obj.insert(插入位置,‘文本内容’) obj.delete(从哪里开始,到哪之前结束)
from tkinter import *
root = Tk()
e = Entry(root)
e.pack(padx=20, pady=20)
e.insert(0,"默认文本") # 插入默认文本
e.delete(1,2) # 清除下标为 1 的元素
e.delete(0,END)# 清除文本框
mainloop()
Entry() 参数show: 指定显示的文本是什么
参数sticky:默认控件在窗口的对齐方式
sticky=N/S/E//W:顶端对齐/底端对齐/右对齐/左对齐
sticky=N+S/ NS:拉伸高度,使其在水平方向上顶端和底端都对齐
sticky=E+W/ EW,拉伸宽度,使其在垂直方向上左边界和右边界都对齐 还有:SE SW NW NE......
sticky=N+S+E/ NSE:拉伸高度,使其在水平方向上对齐,并将控件放在右边(当两个控件放在同一行同一列时效果明显)
# 1、用指定的符号代替某一文本框的内容:——Entry的show参数赋值
# 2、StringVar()作用?
from tkinter import *
root = Tk()
# 注意:Label首字母应该大写!!!
Label(root,text="账号:").grid(row=0,column=0) #三种管理组建的方式 pack、read、
Label(root,text="密码:").grid(row=1,column=0)
v1 = StringVar() # 指定输入为字符型
v2 = StringVar()
e1 = Entry(root,textvariable=v1)
e2 = Entry(root,textvariable=v2,show='*')
e1.grid(row=0,column=1,padx=10,pady=5)
e2.grid(row=1,column=1,padx=10,pady=5)
# 添加2个按钮
def show():
# 打印作品等
print("账号:《%s》" % e1.get()) # obj.get()表示获取textvariable内容
print("密码:%s " % e2.get())
# 清空两个Entry
Button(root,text="芝麻开门",width=10, command=show)\
.grid(row=3,column=0,sticky=W,padx=10,pady=5) # sticky 类似于anchor方法
Button(root,text="退出",width=10,command=root.quit)\
.grid(row=3,column=1,sticky=E,padx=10,pady=5)# 清空动作,使用obj.quit 方法
mainloop()
Entry() 判断文本是否符合要求: 参数validate 参数validatecommand
参数validate 设置判断开关:
# foucusout失去焦点时验证 focusin 获得焦点时验证 focus 失去或者获得时验证 key 输入框被编辑时验证
# all上面任意一种情况时验证 none关闭验证功能(默认)
参数validatecommand :指定只能返回True False的验证函数, 该验证函数需要知道输入框输入的内容,通过Entry组件中get()方法 (见例1)
参数invalidatecommand: 只有在validatecommand返回False时才会被调用(见例2)
# 例1: 判断
from tkinter import *
master = Tk()
def test():
if e1.get() == "小甲鱼":
print("正确!")
return True
else:
print("错误!")
e1.delete(0,END) # obj.delete(从下标为几的元素开始,到下标为几的元素之!前!结束
return False
v = StringVar()
e1 = Entry(master,textvariable=v,validate="focusin",validatecommand=test)
# 参数validate 设置判断开关:
# foucusout失去焦点时验证 focusin 获得焦点时验证 focus 失去或者获得时验证 key 输入框被编辑时验证
# all上面任意一种情况时验证 none关闭验证功能(默认)
e2 = Entry(master)
e1.pack(padx=10,pady=10)
e2.pack(padx=20,pady=50)
mainloop()
# 例2
from tkinter import *
master = Tk()
v = StringVar()
def test1():
if v.get() == " hh":
print("correct!")
return True
else:
print("wrong!")
e1.delete(0,END) # 清空
return False
def test2():
print("我被调用了")
return True
e1 = Entry(master,textvariable=v,validate="focusout",\
validatecommand=test1,invalidcommand=test2)
e2 = Entry(master)
e1.pack()
e2.pack()
mainloop()
Entry组件的参数validatecommand的 验证函数 f 和额外参数s1、s2、s3......
validatecommand=(f, s1, s2, s3,.....) 注意:f 在之前就需要使用 根对象.register(用户自定义函数)方法 冷却包装
from tkinter import *
master = Tk()
v = StringVar()
def test(content,reason,name):
if content == "hhhh":
print("correct!")
print(content,reason,name)
return True
else:
print("wrong!")
print(content,reason,name)
return False
testCMD = master.register(test)
# 用obj.register()将验证函数(此处为test)包装起来,因为在使用隐藏功能选项之前需要冷却
e1 = Entry(master, textvariable=v, validate="focusout",\
validatecommand=(testCMD,'%P','%v','%W')).pack(padx=10,pady=10)
# validatecommand(验证函数名f,额外参数s1,额外参数s2,...) s1、s2 会作为参数依次传给f验证函数
# %P:输入框的值允许改变时,该值有效
# %v:validate值
# %W:组件名字 用一串数字来表示?
e2 = Entry(master)
# e1.pack(padx=10,pady=10)
e2.pack()
mainloop()
加法计算器 综合
# 加法计算器
from tkinter import *
master = Tk()
frame = Frame(master)
frame.pack(padx=10, pady=10)
v1 = StringVar()
v2 = StringVar()
v3 = StringVar()
def test(content):
return content.isdigit()
testCMD = frame.register(test)
# validate指定为key时,有任何输入操作都会拦截,
#然后被调用验证函数。验证完毕后,只有函数返回True,
#他才会将内容返回到特性valiable关联的变量里面。
#False时会自动清除
# width=几,改变框架的长度。可变字体耳朵宽度*10设为输入框的宽度
e1 = Entry(frame, width=10, textvariable=v1, validate="key",\
validatecommand=(testCMD,'%P')).grid(row=0, column=0) # 设置位置,%P:当输入框的值允许改变时,该值有效,返回值为输入框最新文本内容
Label(frame, text=' + ').grid(row=0, column=1)
e2 = Entry(frame, width=10, textvariable=v2, validate="key",\
validatecommand=(testCMD,'%P')).grid(row=0,column=2)
Label(frame, text=' = ').grid(row=0,column=3)
e3 = Entry(frame, textvariable=v3, state='readonly').grid(row=0,column=4) # state参数设置为只读形式
def calc():
result = int(v1.get())+int(v2.get())
v3.set(str(result))
Button(frame, text=" 计算结果 ", command=calc).grid(row=1,column=2, pady=5)
mainloop()
Listbox组件:支持滚动条 setgrid=True , command 参数与 lambda函数结合设置删除, selectmode确定选择模式
command = lambda x=值对象 :要进行的操作比如删除x.delete(ACTIVE) ACTIVE表示当前被选中的项目
#例1 简单了解:
from tkinter import *
root = Tk()
theLB = Listbox(root, setgrid=True)
theLB.pack()
for item in range(12):
theLB.insert(END,item)
theButton = Button(root, text='delete', command= lambda x=theLB : x.delete(ACTIVE)).pack()
mainloop()
# 例2:
from tkinter import *
master = Tk()
# 定义一个Lisbox对象,使可以多选,参数selectmode设置怎样选择
# SINGLE | 单选 | BROWSE |单选,但可以通过拖动鼠标或方向键直接改变方向
# MULTIPLE| 多选 | EXTENDED |多选,但需要同时按住Shift或Ctrl键
theLB = Listbox(master, selectmode=EXTENDED)
theLB.pack()
theLB.insert(0,"你是猪")
theLB.insert(END,"我是猪")
# 当选项太多时,用迭代
for item in ["张三","李四","王二麻子"]:
theLB.insert(END, item) # END 表示每次最后的位置
theLB.delete(0,1) # 删除,obj.delete(从第几个元素下标,到第几个元素下标)注意区别!!!!!!!
# 另一种删除方式: 设置Button键,选一个删一个面结合lambda函数
# 赋值 = lambda 参数 : 参数要实现的运算
"""
def get_y(a, b):
return lambda x : ax + b
y = get_y(1,1)
y(1)
# 输出为 2
"""
theButton = Button(master, text="删掉它",\
command=lambda x=theLB:x.delete(ACTIVE)) # 利用独立按钮删除被选中的那一项
theButton.pack()
# 疑问: 为什么我的选项不是随着拖动鼠标移动
mainloop()
通过修改Listbox的参数height,增加界面可以显示的最多行数
from tkinter import *
master = Tk()
theLB = Listbox(master, selectmode=EXTENDED, height=11)
theLB.pack()
theLB.insert(0,"你是猪")
theLB.insert(END,"我是猪")
for item in range(11):
theLB.insert(END, item)
theLB.delete(0,1)
theButton = Button(master, text="删掉它",\
command=lambda x=theLB:x.delete(ACTIVE))
theButton.pack()
# 修改hight选项,指定Listbox显示的行数,默认10行
mainloop()
Scrollbar组件:设置垂直滚动条
# 适应垂直滚动条
from tkinter import *
root = Tk()
sb = Scrollbar(root) # Scrollbar组件定义垂直滚动条 定义滚定条对象sb
sb.pack(side=RIGHT, fill=Y) # 填满Y轴,可以自己试试X
#注意: side可为TOP BUTTOM RIGHT LEFT 大写时可不适用''号
ib = Listbox(root, yscrollcommand=sb.set) # 设置yscrollcommand为sb的set方法
for i in range(20):
ib.insert(END,i)
ib.pack(side=LEFT, fill=BOTH)
sb.config(command=ib.yview)# 通过sb的config方法设置参数command为yview方法
mainloop()
Scale组件: 通过滑块来表示某一范围内的数字
# scale组件: 通过滑块来表示某一个范围内的数字
from tkinter import *
root = Tk()
Scale(root, from_=0, to=42).pack() # from关键字,所以用from_
Scale(root, from_=0, to=200, orient=HORIZONTAL).pack() # 默认为Vertical
mainloop()
# scale组件+ 获取当前位置: command 函数,与obj.get()结合获取当前位置
from tkinter import *
root = Tk()
s1 = Scale(root, from_=0, to=42)
s1.pack() # s1 = Scale(XXXXXX).pack 因为这步表示给s1赋值,所以不可以将pack连载Scale后面
s2 = Scale(root, from_=0, to=200, orient=HORIZONTAL)
s2.pack()
def show():
print(s1.get(), s2.get())
Button(root, text="获取位置", command=show).pack()
mainloop()
Scale组件中,resolution设置每次移动的像素即步长, tickinterval 设置刻度, length设置条长度
# 通过reserlution设置步长和精度
from tkinter import *
root = Tk()
Scale(root, from_=0, to=42, tickinterval=5, resolution=5, length=200).pack() # from关键字
Scale(root, from_=0, to=200, tickinterval=5, resolution=10, orient=HORIZONTAL, length=600).pack()
# tickinterval设置刻度,resolution 设置移动条每次移动的像素,即步长,length设置条长度
mainloop()
三、
Text组件:处理多行文本
# Text组件
from tkinter import *
root = Tk()
text = Text(root, width=30, height=5)
text.pack()
text.insert(INSERT, "哈哈哈 \n ")# 在输入光标插入
text.insert(END,'hhh\n')
text.insert(END,'LLL')
# 插入到最后
mainloop()
Text组件:可以插入window组件 用Button
# Text组件 插入对象、图片
from tkinter import *
root = Tk()
text = Text(root, width=30, height=5)
text.pack()
text.insert(INSERT, "哈哈哈 \n ")# 在输入光标插入
text.insert(END,"hhh\n")
def show():
print("我被点了!!")
#这里写text和root有区别吗?
b1 = Button(text, text="点我点我", command=show)
text.window_create(INSERT, window=b1) #按钮的实例
mainloop()
Text组件: 还支持插入图片
图片对象 = PhotoImage(file=路径)
按钮对象b1 = Button(text ,......后续操作, command=操作函数)
def 操作函数(): text.image_create(END, image=photo) # 将图片插在指定位置,此处为end
text.window_create(INSERT, window=按钮对象b1 )
# Text组件 插入对象、图片
from tkinter import *
root = Tk()
text = Text(root, width=50, height=50)
text.pack()
text.insert(INSERT, "哈哈哈 \n ")# 在输入光标插入
text.insert(END,"hhh\n")
photo = PhotoImage(file=r".\best wishes.gif")
def show():
text.image_create(END,image=photo)
#这里写text和root有区别吗?
b1 = Button(text, text="点我点我", command=show)
text.window_create(INSERT, window=b1) #按钮的实例
mainloop()
效果截图:
Text组件中Mark:指定字符串位置,并跟随相应字符串一起移动
Mark中: INSERT 指定当前插入光标的位置 CURRENT 紧按鼠标松开才会相应 Mars 用户自定义
Mark中,行从1开始,列从0开始
Text对象text.mark_set('标签名', row . column 行.列位置 )
Text对象text.insert('标签', '要插入的内容')
text.mark_useset('标签名') 只有用这个方法才可以删除标签,而不是text.delete(0,END)方法
text.mark_gravity('标签‘,LEFT)插入标签的右侧,即每次输入插到上一次输入元素的左侧。默认是插入右侧
# text组件中使用index
#1、line.column
#2、line.end 末尾
#3、insert、end
#4、expressions 用于修改任何形式的索引>>>def backpace(event): # 演示删除插入光标的前一个字符
event.widget.delete("%s - 1c" % INSERT, INSERT) # - count chars = - count c
# Mark ↓↓
from tkinter import *
root = Tk()
text = Text(root, width=30, height=7)
text.pack()
text.insert(INSERT,'Hey!') # 插入 Hey!
text.mark_set('mark',1.2) # 标记y,y的row为1,column为2的字符(Mark标记中,行用1开头,列用0开头)
text.insert('mark','insert') # 在1.2的左边插入指定元素
# 一般默认插入元素在标记的左边,若要插在标记的右边,则需要mark_gravity()方法
text.insert('mark','1')
text.insert('mark','2')
text.insert('mark','3')
# 此时的输出为: Heinsert123y!
text.delete(1.0, 1.5) # 按照输出的字符串标记(开始下标,结束下标的前一个元素)
# 此时的输出为: ert123y!
text.insert('mark','4')
text.mark_unset('mark')
# 此时的输出为: ert1234y!
# obj.mark_gravity()方法的使用:
text.mark_set('mark',1.1) # 在原来的输出上,重新设置标签,1.1为元素‘r’
#(1.1)也随着新加入的字符串不断变化着
text.mark_gravity('mark',LEFT) # LEFT声明,mark始终位于左边,即插入元素始终在右边
text.insert('mark','嘿')
text.insert('mark','哈')
text.insert('mark','呼')
# 输出为:e呼哈嘿rt1234y!
mainloop()
Tag用法:
text.tag_add('标签', 'row.column')
text.tag_config('标签', background='', foreground='', .............)
图片: tag_config 可使用的选项:
# Text Tag用户自定义Tag和预定义的Tag:SEL
from tkinter import *
root = Tk()
text = Text(root, width=50, height=10) # width height设置文本框宽度
text.pack()
text.insert(INSERT,"I Love FishC.com!")
text.tag_add('tag1','1.7','1.12','1.14')
text.tag_config('tag1',background='pink',foreground='red')
# 对同一个文本设置多个Tag,新的会覆盖旧的
text.tag_add('tag2','1.7','1.12','1.14')
text.tag_config('tag2',background='blue')
#tag_raise() tag_lower() 设置Teg优先级,否则背景色就是蓝的
text.tag_lower('tag2')
text.insert(INSERT,'I love fishc',('tag1','tag2'))
mainloop()
Tag包含网页
import webbrowser text.tag_bind('标签','< >',函数) webbrowser.open("网址")
# Text 支持事件绑定
from tkinter import *
import webbrowser
root = Tk()
text = Text(root, width=50, height=50)
text.pack()
text.insert(INSERT,'I love fishc.com!')
text.tag_add('link','1.7','1.16')
text.tag_config('link', foreground='pink', underline=True) #
# 事件绑定 tag 也作为 index的一部分 表鼠标进入
def show_arrow_cursor(event): # 绑定事件时要有event参数
text.config(cursor='arrow')
def show_xterm_cursor(event):
text.config(cursor='xterm')
def click(event):
webbrowser.open("http://www.fishc.com")
text.tag_bind('link','', show_arrow_cursor)
text.tag_bind('link','', show_xterm_cursor)
text.tag_bind('link','
text 组件中 MD5 :判断内容是否发生变化
# 判断内容是否变化 验证文本的md5 来判断是否改变
from tkinter import *
import hashlib
root = Tk()
text = Text(root, width=50, height=30)
text.pack()
text.insert(INSERT, 'I love fishc.com!')
contents = text.get('1.0',END) # 获取内容
def getSig(contents): # 2
m = hashlib.md5(contents.encode()) # 获取contents的md5的值,首先需要将contents转换为二进制
return m.digest() # obj.digest() 返回摘要
sig = getSig(contents) # 3
def check(): # 1
contents = text.get('1.0',END) # 1.a
if sig != getSig(contents): # 4.b,sig 的值在之前已经得出
print("未保存!")
else:
print("安全!")
Button(root, text="检查", command=check).pack()
mainloop()
text下的search()方法:
text.search('要找的内容',start开始的地方,stopindex = END,backwards) 参数stopindex表示直到文本末尾结束搜索
backwards
复习:正则表达式的search()
>>>import re
>>>print(re.search("tion","funnction"))
打印结果 <_sre.SRE_Match object; span=(4, 8), match='tion'>
>>>print(re.search("tion","function")).span()
打印结果 (4, 8)
Text的撤销、恢复操作:
undo = True : edit_undo() 撤销 / edit_redo() 恢复
autoseparators = False : edit.separator() 在依次完整的操作后插入分隔符
# 参数undo 与edit_undo()方法
from tkinter import *
root = Tk()
text = Text(root, width=30, height=10, undo=True)
text.pack()
text.insert(INSERT, "I love fishc.com")
def show():
text.edit_undo()
Button(root, text='撤销', command=show).pack()
mainloop()
# Text组件:支持输入和撤销(删除后恢复)
# 撤销栈 压栈、出栈 先进后出
from tkinter import *
import hashlib
root = Tk()
text = Text(root, width=50, height=30, undo=True, autoseparators=False)# 参数autoseparators
text.pack()
text.insert(INSERT,'I love fishC.com')
def callback(event): # 此处,event参数是绑定必须有的。输入一个插入一个分隔符,以免撤销时将所有内容全部撤回
text.edit_separator()
text.bind('',callback)
def show():
text.edit_undo() # 首需要保证在定义text时申明了undo=True,否则没有用
Button(root, text='撤销', command=show).pack()
mainloop()
create_line(weidth, heigth, width, heigth, fill=color, dash=(虚线参数, 虚线参数)) create_rectangles( ......) create_形状()
from tkinter import *
root = Tk()
w = Canvas(root, width=200, height=100, bg='violet')
w.pack()
w.create_line(0, 50, 200, 50, fill='yellow')
w.create_line(100, 0, 100, 100, fill='blue',dash=(4,4))
w.create_rectangle(50, 25, 150, 75, fill='pink')
#rectanglr会覆盖之前的方法
mainloop()
coords(图像,移动的位置......) itemconfig(图像,fill= new color) move() 修改的方法 obj.delete(图像)
from tkinter import *
root = Tk()
w = Canvas(root, width=200, height=100)
w.pack()
line1 = w.create_line(0, 50, 200, 50, fill='violet')
line2 = w.create_line(100, 25, 100, 75, fill='blue', dash=(4, 5))
rect1 = w.create_rectangle(50, 25, 150, 75, fill='pink')
#修改三种方法:coords() itemconfig() move()
w.coords(line1, 0, 25, 200, 25)# 移动图像(对象,需要的操作)
w.itemconfig(rect1, fill='red') # 修改颜色
w.delete(line2) # 删除对象
Button(root, text='删除所有', command=(lambda x=ALL : w.delete(x))).pack() #使用lambda表达式 lambda 参数:运算
mainloop()
设置文本框 create_text(位置,text=‘XXX’)
from tkinter import *
root = Tk()
w = Canvas(root, width=200, height=100)
w.pack()
w.create_line(0, 0, 200, 100, fill='green', width=3)
w.create_line(200, 0, 0, 100, fill='green', width=3)
w.create_rectangle(40, 30, 160, 70, fill='green')
w.create_rectangle(65, 35, 135, 65, fill='yellow')
w.create_text(100, 50, text='FishC') # (100, 50)位于画布正中间的位置
mainloop()
设置椭圆 create_oval(),借用 create_rectangle()绘制出矩形来绘制椭圆
from tkinter import *
root = Tk()
w = Canvas(root, width=200, height=100)
w.pack()
w.create_rectangle(160, 20, 190, 50, dash=(4,7))
w.create_oval(160, 20, 190, 50, fill='violet')
w.create_text(175, 35, text='hey') # (175, 35)正好是最中间的位置
w.create_rectangle(40, 20, 160, 80, dash=(4,6)) # 椭圆的限定矩形
w.create_oval(70, 20, 130, 80, fill='pink')
w.create_text(100, 50, text='FishC')
mainloop()
绘制五角星 create_polygon(操作的点集,fill= ,outline= ) point集合
from tkinter import *
import math as m
root = Tk()
w = Canvas(root, width=200, height=100)
w.pack()
center_x = 100
center_y = 50
r = 50
points = [
#左上点
center_x - int(r * m.sin(2*m.pi / 5)),
center_y - int(r * m.cos(2*m.pi / 5)),
#右上点
center_x + int(r * m.sin(2*m.pi /5)),
center_y - int(r * m.cos(2*m.pi / 5)),
#左下点
center_x - int(r * m.sin(2*m.pi / 10)),
center_y + int(r * m.cos(2*m.pi / 10)),
#最上方点
center_x, center_y - r,
#右下点
center_x + int(r * m.sin(2*m.pi / 10)),
center_y + int(r * m.cos(2*m.pi / 10))
]
# 或者后两个写 center ± r * m.sin/cos(m.pi / 5)
w.create_polygon(points, fill='yellow', outline='blue') # fill 默认为黑, outline和fill=''时为透明色
mainloop()
绘制画布: (技巧: 用n个无限小的椭圆/点 构成线条)
event.x event.y 获得鼠标实时位置
from tkinter import *
root = Tk()
w = Canvas(root, width=200, height=100)
w.pack()
def paint(event):
x1, y1 = (event.x - 1), (event.y - 1)
x2, y2 = (event.x + 1), (event.y + 1)
w.create_oval(x1, y1, x2, y2, fill='red')
w.bind("",paint)
Label(root, text="按住鼠标左键开始移动,开始绘图吧~").pack(side=BOTTOM)
mainloop()
- Canvas支持的对象: arc 、bitmap(内建的位图文件或XBM格式的文件)、image(BitimapImage或PhotoImage的实例对象)、line、oval、polygon(多边形)、rectangle、text、window(组件)
- 坐标系:窗口坐标系(窗口左上角为原点)、画布坐标系(画布左上角为原点)
- 画布对象: Item handles、 Tags(ALL、CURRENT)
menu对象.add_command(label='标签',command=函数)
#设计弹出、下拉菜单
from tkinter import *
root = Tk()
menubar = Menu(root)
def callback():
print("你好!")
menubar.add_command(label="hello", command=callback)
menubar.add_command(label="quit", command=root.quit)
root.config(menu=menubar) # 显示菜单
mainloop()
一级菜单、二级菜单 Menu()的参数 tearoff=False : 不允许将菜单拉出来
一级菜单对象.casecade(label='一级菜单名',menu=二级菜单名)
menu对象.add_separator() # 添加分割线
# 下拉菜单:添加到主菜单上(而不是窗口上)
from tkinter import *
root = Tk()
menubar = Menu(root)
def callback(): # 为什么这里没有event? 答:不是绑定
print("你好~")
# tearoff=True可以将菜单拉出来
filemenu = Menu(menubar, tearoff=False) # 定义filemenu
menubar.add_cascade(label="文件", menu=filemenu)# 也可以写到最前面
filemenu.add_command(label="打开", command=callback)
filemenu.add_command(label="保存", command=callback)
filemenu.add_separator() # 添加分割线
filemenu.add_command(label="退出", command=root.quit) # 调用root下的quit方法
# menubar.add_cascade(label="文件", menu=filemenu) # 在menubar上创建级联菜单,用obj.add_cascade(标签名,下一级的菜单)
editmenu = Menu(menubar)
menubar.add_cascade(label="编辑", menu=editmenu)#同理
editmenu.add_command(label="剪切", command=callback)
editmenu.add_command(label="拷贝", command=callback)
editmenu.add_command(label="粘贴", command=callback)
# menubar.add_cascade(label="编辑", menu=editmenu)
root.config(menu=menubar) #
mainloop()
右键弹出菜单操作
# 处理弹出菜单
from tkinter import *
root = Tk()
def callback():
print("你好~")
menubar = Menu(root)
menubar.add_command(label="撤销", command=callback)
menubar.add_command(label="重做", command=callback)
frame = Frame(root, width=512, height=512)
frame.pack()
def popup(event): # 事件绑定
menubar.post(event.x_root, event.y_root) #弹出
frame.bind("", popup) # 点击鼠标右键,执行相应操作
mainloop()
与IntVar() add_checkbutton(label=‘’, command=函数, variable=)
和 add_radiobutton(label=‘’, command=,variable=, value=几) 结合使用
from tkinter import *
root = Tk()
menubar = Menu(root)
def callback():
print("HelloMM")
#多选:
openVar = IntVar()
saveVar = IntVar()
quitVar = IntVar()
filemenu = Menu(menubar)
filemenu.add_checkbutton(label="打开", command=callback, variable=openVar)
filemenu.add_checkbutton(label="保存", command=callback, variable=saveVar)
filemenu.add_separator()
filemenu.add_checkbutton(label="退出", command=root.quit, variable=quitVar)
menubar.add_cascade(label="文件", menu=filemenu)
#单选:
editVar = IntVar()
editmenu = Menu(root, tearoff=False)
menubar.add_cascade(label="编辑", menu=editmenu)
editmenu.add_radiobutton(label="剪切", command=callback, variable=editVar, value=1)
editmenu.add_radiobutton(label="拷贝", command=callback, variable=editVar, value=2)
editmenu.add_radiobutton(label="黏贴", command=callback, variable=editVar, value=3)
root.config(menu=menubar)
mainloop()
# Menubutton()
from tkinter import *
root = Tk()
def callback():
print("漂亮MM ")
plmm = Menubutton(root, text="点我~",relief=RAISED) # frlif 设置悬浮在
plmm.pack()
filemenu = Menu(plmm, tearoff=False)
filemenu.add_command(label="打开", command=callback)
filemenu.add_command(label="关闭", command=callback)
filemenu.add_separator()
filemenu.add_command(label="走了", command=root.quit)
plmm.config(menu=filemenu)
mainloop()
# Optionmenu()
from tkinter import *
root = Tk()
variable = StringVar()
variable.set(1) # 默认
w = OptionMenu(root, variable, 1, "two", "3") #可变参:可添加元素
w.pack()
mainloop()
在OptionMenu组件中添加选项
# 一个 * 表示元组:
>>> def fun1(*args):
print(type(args))
print(args)
>>> fun1(1, 2, 3, 4, 5)
(1, 2, 3, 4, 5)
# 两个 ** 表示字典:
>>> def fun2(**hh):
print(type(hh))
print(hh)
>>> fun2(a=1, b=2, c=3)
{'a': 1, 'b': 2, 'c': 3}
# * 作为参数,表示通过解包参数调用函数,
# 通过在实参前加一个星号(*)或两个星星号(**),来对列表、元组或字典进行解包>>> a = [1, 2, 3, 4, 5]
>>> b = [1, 2, 3, 4, 5]
>>> fun1(*a)
(1, 2, 3, 4, 5)>>> c = {"one":1, "two":2}
>>> fun2(**c)
{'one': 1, 'two': 2}
# 如何添加选项在OptionMenu中
from tkinter import *
root = Tk()
OPTIONS = [
"California",
"458",
"FF",
"ENZO",
"LaFerrari"
]
variable = StringVar()
variable.set(OPTIONS[0])
w = OptionMenu(root, variable, *OPTIONS)
# 一个* 表示打包成元组
# 两个* 表示打包成字典
w.pack()
mainloop()
# 鼠标按键的位置
from tkinter import *
root = Tk()
def callback(event):
print("点击位置:", event.x, event.y)
# 从窗口左上角(0,0)位置开始,区别于root_x/y
# root_x root_y: 从屏幕左上角开始
frame = Frame(root, width=200, height=200)
frame.bind("", callback)# <操作-具体描述> Button中,1代表左键,2代表中间键,3代表右键,4、5不管。
frame.pack()
mainloop()
focus_set() 只有当组件接受键盘焦点时才可以接受键盘事件
frame 的参数takefocus
#键盘事件
from tkinter import *
root = Tk()
def callback(event):
print(event.char) # obj.char 对应字符
print(event.keysym) # obj.keysym 可获得键盘上其他出字母键的特殊键
print(event.keycode) # obj.keycode 按键码
frame = Frame(root, width=200, height=200)
frame.bind("", callback)
frame.focus_set() # 只有当组件获得焦点时,才可以接受键盘事件Key
frame.pack()
mainloop()
# 鼠标实时位置,顶鼠标进入组件时响应
from tkinter import *
root = Tk()
def callback(event):
print(event.x, event.y)
frame = Frame(root, width=200, height=200)
frame.bind('', callback)
frame.pack()
mainloop()
事件序列:<可选modifier - 必须type - 可选detail >
type常用关键字
modifier关键词
Event对象
支持自动&手动换行
# 利用Message()实现换行、调节尺寸使适应给定的尺寸
from tkinter import *
root = Tk()
w1 = Message(root, text="消息", width=100)
w1.pack()
w2 = Message(root, text="ha\nhahahahaahahaha")
# 同时, \n 也支持换行
w2.pack()
mainloop()
Spinbox(root, from_ = XXXX, to=XXXX, increment步长,invcmd, warp 循环)
# Spinbox()用特定的数据中提取一个值出来,一定情况下代替Entry()
from tkinter import *
root = Tk()
w = Spinbox(root, from_=0, to=10, increment=2, wrap=2) # increment 步长精度,invcmd与invalidcommand一样,wrap设置循环
w.pack()
mainloop()
Spinbox( root, values=(元组))
# 设置组件,给一组字符串,实现选择
from tkinter import *
root = Tk()
w = Spinbox(root, values=('1','2','3')) # 元组
w.pack()
mainloop()
PanedWindow() 划分窗格
# PanedWindow()为子组件提供一个框架,与Frame()组件类似,允许用户自己对框架内的空间进行划分
from tkinter import *
m = PanedWindow(orient=VERTICAL) # orient 设置方式
m.pack(fill=BOTH, expand=1)
top = Label(m, text='top pane')
m.add(top)
botton = Label(m, text='botton pane')
m.add(botton)
mainloop()
# 拖住左键可以上下移动窗格
利用orient的默认horizontal 来划分窗格
from tkinter import *
m1 = PanedWindow()
m1.pack(fill=BOTH, expand=2)
left = Label(m1, text='left pane')
m1.add(left)
m2 = PanedWindow(orient=VERTICAL)
m1.add(m2)
top = Label(m2, text='top pane')
bottom = Label(m2, text='bottom pane')
m2.add(top)
m2.add(bottom)
mainloop()
PanedWindow() 参数handlepad 设置手柄起点 showhandle显示手柄 sashrelief设置分割线样式
# 分隔线
from tkinter import *
m1 = PanedWindow(handlepad=100, showhandle=True, sashrelief=SUNKEN)
#handlepad设置手柄据起点的像素 showhandle显示手柄 sashrelief设置分隔线样式 sunken沉没式
m1.pack(fill=BOTH, expand=2)
left = Label(m1, text='left pane')
m1.add(left)
m2 = PanedWindow(orient=VERTICAL,showhandle=True, sashrelief=SUNKEN)
m1.add(m2)
top = Label(m2, text='top pane')
bottom = Label(m2, text='bottom pane')
m2.add(top)
m2.add(bottom)
mainloop()
创建顶级窗口
# Toplevel组件 需要显示额外的窗口、对话框和其他窗口,与root相似
from tkinter import *
root = Tk()
def create():
top = Toplevel() #创建顶级窗口
top.attributes("-alpha",0.5)
# obj.attributes("-参数名",设置的透明度)方法里的alpha参数可以设置透明度,注意()内参数的使用
top.title("hankeyu")
msg = Message(top, text="MIS")
msg.pack()
Button(root, text="创建顶级窗口", command=create).pack()
mainloop()
# 会出现很多独立小窗口
pack()
# 布局管理器:pack(按添加的顺序)、pick(按行列形式排列)、place(自定义)
# 注意:不要在同一个父类中混合使用pack和grid
from tkinter import *
root = Tk()
listbox = Listbox(root)
listbox.pack(fill=BOTH, expand=True)# fill填充,expand表示将额外空间也同时填满
for i in range(10):
listbox.insert(END,str(i))
mainloop()
pack()设置横纵向填充
from tkinter import *
root = Tk()
# side 设置左对齐,横向填充
Label(root, text='red', bg='red', fg='white').pack(fill=X, side=LEFT)#X表示横向填充,Y纵,BOTH两方向都
Label(root, text='green', bg='green', fg='black').pack(fill=Y, side=LEFT)
Label(root, text='blue', bg='blue', fg='white').pack(fill=X, side=LEFT)
mainloop()
grid() sticky设置对齐方式
# grid
from tkinter import *
root = Tk()
Label(root, text='用户名').grid(row=0, sticky=W) # sticky=W 设置左对齐
Label(root, text='密码').grid(row=1, sticky=W)
Entry(root).grid(row=0, column=1)
Entry(root, show='@@').grid(row=1, column=1)
mainloop()
结合PhotoImage()用grid将图片插入
# grid
from tkinter import *
root = Tk()
photo = PhotoImage(file=r'.\food.gif')
Label(root, image=photo).grid(row=0, column=4, rowspan=2,padx=50, pady=10)# rowspan 表示跨两行
# 原始版:Label(root, image=photo).grid(row=0, column=2)
Label(root, text='用户名').grid(row=0, sticky=W) # sticky=W 设置左对齐
Label(root, text='密码').grid(row=1, sticky=W)
Entry(root).grid(row=0, column=1)
Entry(root, show='@@').grid(row=1, column=1)
Button(text='提交', width=10).grid(row=2, columnspan=3, pady=6) # columnspan表示跨三列,设置宽度为5
mainloop()
place() relx rely 表示相对附件的位置, 0.5 正中央,1最右,0最左
# place relx rely 表示相对副主件的位置,0.5表示正中央,1表示最右边,0最左
# 一个主件覆盖另一个主件
from tkinter import *
root = Tk()
photo = PhotoImage(file=r'.\food.gif')
Label(root, image=photo).pack()
def callback():
print("正中靶心!")
Button(root, text='正中靶心!', command=callback).place(relx=0.5, rely=0.5, anchor=CENTER)
mainloop()
place的reheight、reweidth参数
# 设置相对于副主件的大小尺寸
# forget:从屏幕上删除
from tkinter import *
root = Tk()
Label(root, bg='pink',).place(relx=0.5, rely=0.5, relheight=0.4, relwidth=0.75, anchor=CENTER)
Label(root, bg='yellow').place(relx=0.5, rely=0.5, relheight=0.5, relwidth=0.5, anchor=CENTER)
mainloop()
showwarning(title标题, message文本, option)
default、icon指定图标ERROR INFO QUESTION WARNING、parent,显示在哪个子窗口上askokcancel()
askquestion()
filedialong模块:
askopenfilename()打开文件 asksaveasfilename()保存文件
defaultextention="某后缀"
import tkinter.messagebox
tkinter.messagebox.askokcancel('mention','this is a message box')
#正确
tkinter.filedialog
from tkinter import *
import tkinter.filedialog
root = Tk()
def callback():
filename = tkinter.filedialog.askopenfile(defaultextention='.py')
print(filename)
Button(root, text='打开文件', command=callback).pack()
mainloop()
# 输入文件名,不加后缀的话会被自动加入指定后缀,加了后缀的话如果和设置的不相符,就不会找到相应文件
# 不用defaultextention的话,输入文件名不加后缀,电脑找不到相应文件
指定后缀格式,打开文件
# filetypes
from tkinter import *
import tkinter.filedialog # 注意要改成这个! tkinter.啥啥啥
root = Tk()
def callback():
filename = tkinter.filedialog.askopenfilename(filetypes=[('PNG','.png'),('JPG','.jppg'),('GIF','.gif'),('Python','.py')])
Button(root, text='打开文件', command=callback).pack()
mainloop()
tkinter.colorchooser 颜色
# colorchooser
import tkinter.colorchooser
from tkinter import *
root = Tk()
def callback():
color_number = tkinter.colorchooser.askcolor()
print(color_number) # 返回颜色的RGB值
Button(root, text='选择颜色', command=callback).pack()
mainloop()
# 要令引入tkinter.colorchooser