《python》006 tkinter

文章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()

效果截图:

《python》006 tkinter_第1张图片

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()

Canvas组件

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组件

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组件:类似于button,但有下拉菜单

 

# 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组件:用于记录用户选择了什么

# 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()

事件绑定

 

你可能感兴趣的:(python,python)