• Python进阶(二)-图形界面编程Tkinter(2)


    二、图形界面编程

    2.1 事件绑定

    前面章节,我们了解了积木的形状(具体细节,例如每个组件都有哪些属性、方法我们一会儿在讲)、清理了我们搭建的平台(建立主窗口tk)、了解了怎么将积木拼接在一起(组件布局)。
    但是有一点还不够完善,我们怎么跟我们拼接出来的东西互动呢?这就需要用到事件绑定,也叫事件处理。是程序用来接受用户的指令,并做出反应的过程。
    事件处理,是 GUI 程序中不可或缺的重要组成部分,相比来说,控件只是组成一台机器的零部件, 而事件处理则是驱动这台机器“正常”运转的关键所在,它能够将零部件之间“优雅”的贯穿起来,因此“事件处理”可谓是 GUI 程序的“灵魂”,同时它也是实现人机交互的关键。
    对于“事件”这一名词,在讲解控件时也偶尔提及过,在本节我们将对 Tkinter 中的事件处理机制做更为详细的介绍。

    在一款 GUI 程序中,我们将用户对软件的操作统称为“事件”,比如鼠标点击按钮、键盘输入文本以及窗口管理器触发的重绘事件等,这些事件有一个共同的特点,即都是由用户直接或者间接触发的。
    Tkinter为我们提供了两种事件绑定方法:

    1. 使用组件的command属性绑定处理函数(前面我们使用的按钮都使用的这种方式来与用户互动),这里就不在介绍
    2. 使用Widget组件的bind()方法,此方法更灵活,还可以获取事件的相关信息。
      其语法格式如下:
    widget.bind("",func)
    
    • 1

    上述语法中,widget 代表控件的实例对象,之后,采用 bind() 方法进行事件绑定,该函数有两个参数:
    :一个字符串参数,表示事件的类型,并使用“尖括号”的形式进行包裹;
    func:表示事件的处理函数(callback,即回调函数),当触发事件时,Tk 会携带事件对象(Event)去调用 func 方法。

    注意:bind() 方法可以完成事件与处理函数绑定,而使用 unbind() 方法可以将事件与处理函数解绑。

    2.1.1 事件码

    事件类型(也称事件码)是 Tkinter 模块规定的,主要包括鼠标、键盘、光标等相关事件,Tkinter 为其规定了相应的语法格式:

    <modifier-type-detail>
    
    • 1

    上述语法由三部分组成,说明如下:
    <>:事件类型必须包含在“尖括号”内;
    modifier:可选项,事件类型的修饰符,通常用于描述组合键、双击、大写锁定键以及等;
    type:是必不可少的一项,表示事件的具体类型;
    detail:可选项,通常用于描述具体的哪个按键,比如 表示鼠标左键;

    这里有必要对经常使用的 modifier 修饰符做简单的介绍,修饰符可以修改事件的激活条件,比如双击鼠标或者需要同时按下某个键才触发事件,常用的修饰符如下:

    修饰符说明
    Control事件发生时需按下 Control 键
    Alt事件发生时需按下 Alt 键
    Shift事件发生时需按下 Shift 键
    Lock事件发生时需处于大写锁定状态
    Double事件连续发生两次,比如双击鼠标
    Triple事件连续发生三次
    Quadruple事件连续发生四次

    下述表格中介绍了 Tkinter 中经常使用的事件类型,如下所示:

    事件码说明
    单击鼠标左键,简写为,后面的数字可以是1/2/3,分别代表左键、中间滑轮、右键
    释放鼠标左键,后面数字可以是1/2/3,分别代表释放左键、滑轮、右键
    按住鼠标左键移动,和分别表示按住鼠标滑轮移动、右键移动
    转动鼠标滑轮
    双击鼠标左键
    鼠标光标进入控件实例
    鼠标光标离开控件实例
    按下键盘上的任意键
    /按下键盘上的某一个字母或者数字键
    释放键盘上的按键
    回车键,其他同类型键有///
    空格键
    ///方向键
    常用的功能键
    组合键,再比如,表示用户同时点击 Ctrl + Shift + T
    当控件获取焦点时候触发,比如鼠标点击输入控件输入内容,可以调用 focus_set() 方法使控件获得焦点
    当控件失去焦点时激活,比如当鼠标离开输入框的时候
    控件的发生改变的时候触发事件,比如调整了控件的大小等
    当控件的状态从“激活”变为“未激活”时触发事件
    当控件被销毁的时候触发执行事件的函数
    当窗口或组件的某部分不再被覆盖的时候触发事件
    当应用程序至少有一部分在屏幕中是可见状态时触发事件

    2.1.2 Event事件对象

    当事件触发后,Tkinter 会自动将事件对象交给回调函数进行下步的处理,Event 对象包含了以下常用属性:

    属性说明
    widget发生事件的是哪一个控件
    x,y相对于窗口的左上角而言,当前鼠标的坐标位置
    x_root,y_root相对于屏幕的左上角而言,当前鼠标的坐标位置
    char用来显示所按键相对应的字符
    keysym按键名,比如 Control_L 表示左边的 Ctrl 按键
    keycode按键码,一个按键的数字编号,比如 Delete 按键码是107
    num1/2/3中的一个,表示点击了鼠标的哪个按键,按键分为左、中、右
    width,height控件的修改后的尺寸,对应着 事件
    type事件类型

    下面看一组关于“键盘事件”的使用示例:

    from tkinter import *
    # 定义事件函数,必须用event参数
    def show_key(event):
        # 查看触发事件的按钮
        s=event.keysym
        # 将其显示在按钮控件上
        lb.config(text=s)
    root=Tk()
    root.config(bg='#87CEEB')
    root.title("Python学习")
    root.geometry('450x350+300+200')
    root.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
    # 添加一个按钮控件
    lb=Label(root,text='请按键',fg='blue',font=('微软雅黑',15))
    # 给按钮控件绑定事件,按下任意键,然后调用事件处理函数。注意,此处需要在英文状态下进行输入
    lb.bind('',show_key)
    # 设置按钮获取焦点
    lb.focus_set()
    lb.pack()
    # 显示窗口
    root.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注意:在上述示例中,只有当 Label 控件获取焦点后才能接收键盘事件,因此在给控件绑定事件和回调函数后,需要使用 focus_set() 方法来获取焦点。

    下面再看一组关于“鼠标事件”的相关示例:

    # 定义事件函数
    from tkinter import *
    def handleMotion(event):
        lb1['text'] = '你移动了光标的所在位置'
        lb2['text'] = '目前光标位置:x ='+ str(event.x)+';y='+str(event.y)
        print('光标当前位置',event.x,event.y)
    # 创建主窗口
    win = Tk()
    win.config(bg='#87CEEB')
    win.title("Python学习")
    win.geometry('450x350+300+200')
    win.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
    # 创建一个窗体容器frame
    frame = Frame (win, relief=RAISED, borderwidth=2, width=300,height=200)
    frame.bind('',handleMotion)
    lb1 = Label(frame,text='没有任何事件触发', bg='purple', )
    # 使用place进行位置布局,下一节会介绍
    lb1.place (x=20,y=20)
    lb2 = Label(frame,text='')
    lb2.place (x=16,y=60)
    frame.pack(side=TOP)
    # 显示窗口
    win.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2.2 组件介绍

    组件是构成用户界面的基本元素,前面我们讲解了组件的一些通用属性,下面详细讲解各个组件的属性、方法。

    2.2.1 组件支持的两个特殊类

    在讲解组件之前,先了解两个组件中会用到的两个重要属性,Variable和compound,特别是用于组件内容的显示。

    2.2.1.1 Variable类

    我们设想一下,如果一个组件的内容经常发生改变,难道我们要重复的对组件内容进行赋值吗?我们能不能使用一个变量来给组件赋值呢?答案是肯定的,就需要使用Variable变量,因为组件的内容是不允许与普通变量绑定的,只能使用tkinter包下的Variable类的子类进行绑定。这个过程也叫做双向绑定,下表列出了Variable类的子类:

    子类说明
    StringVar()str值得变量
    IntVar()整型值变量
    DoubleVar()浮点值
    BooleanVar()bool值

    Variable类包含了2个方法:

    • set():设置变量值
    • get():获取变量值

    在界面编程的过程中,有时我们需要“动态跟踪”一些变量值的变化,从而保证值的变换及时的反映到显示界面上,但是 Python 内置的数据类型是无法这一目的的,因此使用了 Tcl 内置的对象,我们把这些方法创建的数据类型称为“动态类型”,比如 StringVar() 创建的字符串,称为“动态字符串”。

    下面示例程序示范了将Entry组件与StrinVar进行双向绑定,这样车徐既可以通过该StringVar改变Entry输入框显示内容,也可通过该StringVar获取Entry输入框中的内容。

    from tkinter import  *
    from tkinter import ttk
    
    class App:
        def __init__(self,master):
            self.master = master
            self.iniWidgets()
        def initWidgets(self)
            self.st = StringVar() #定义Variable子类StringVar
            ttk.Entry(self.master,textvariable=self.st,width=24,font=('StSong',20,'bold'),foreground='red').pack(file=BOTH,expand=YES)
            #创建Entry组件,将其textvariable绑定到self.st变量
            f = Frame(self.master).pack()
            b1=ttk.Button(f,text='改变').pack(side=LEFT)
            b2=ttk.Button(f,text='获取').pack(side=LEFT)
            #创建两个按钮
            b1.bind('',self.change)
            b2.bind('',self.get)
        def change(self,event)
            languages = ('C','C++','JAVA','Python','JS')
            import random
            self.st.set(languages[random.randint(0,4)])
            # 使用set()方法设置st,与之绑定的Enter内容也随之改变
        def get(self,event)
            from tkinter import messagesbox
            messagesbox.showinfo(title='输入内容',message=self.st.get())
            #使用get()方法获取st内容,即Entry组件内容
    window = Tk()
    Window.title('variable测试')
    App(Window)
    Window.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    程序说明已经在程序内以注释形式给出。

    2.2.1.2 compound属性

    按钮或Lable等组件同时有text、image两个选项,当两个选项同时指定时,通常image会覆盖text,如果希望同时像是文本和图片,就需要使用compound选项进行控制。
    compound选项支持的属性值如下:

    • None:图片覆盖文字
    • LEFT常量(值为‘left’字符串):图片在左,文本在右
    • RIGHT常量(值为‘right’字符串):图片在右,文本在左
    • TOP常量(值为‘top’字符串):图片在上,文本在下
    • BOTTOM常量(值为‘bottom’字符串):图片在底,文本在上
    • CENTER常量(值为‘center’字符串):文字覆盖在图片上方

    下面通过一个程序示例,来改变compound的值:

    from tkinter import *
    from tkinter import ttk
    class App:
        def __init__(self,master):
            self.master = master
            self.initWidgets():
        def initWidgets(self):
            bm = PhotoImage(file='serial.png')  
            #创建一个位图
            self.lable = ttk.Lable(self.master,text='文字图片展示',image=bm,font=('StSong',20,'blod'),foreground='red')
            self.lable.bm = bm
            # 创建一个包含图片文字属性的Lable,并进行简单设置
            self.lable['compound']=None 
            # 设置compound默认属性为None
            self.lable.pack()
            f = ttk.Frame(self.master)
            f.pack(fill=BOTH,expand=YES)
            compounds = ('None','LEFT','RIGHT','TOP','BOTTOM','CENTER')
            self.var = StringVar()
            self.var.set('None')
            #定义一个双向绑定变量,用于绑定Radiobutton的变量
            for val in compounds:
                rb = Radiobutton(f,text=val,padx=20,variable = self.var,command=self.change_compound,value = val).pack(side=LEFT,anchor=CENTER)
            #使用循环创建多个单选按钮
            def change_compound(self):
                self.lable['compound'] = self.var.get().lower()
            #定义一个可以改变lable的compound选项的函数
    root = Tk()
    root.title('compound测试')
    App(root)
    root.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    2.2.2 Lable标签、Message组件

    Label(标签)控件,是 Tkinter 中最常使用的一种控件,主要用来显示窗口中的文本或者图像,并且不同的 Lable(标签)允许设置各自不同的背景图片。Lable通常用来显示不可修改的内容。

    下面对 Label(标签)的常用属性做简单介绍:

    属性名称说明
    anchor控制文本(或图像)在 Label 中显示的位置(方位),通过方位的英文字符串缩写(n、ne、e、se、s、sw、w、nw、center)实现定位,默认为居中(center)
    bg用来设置背景色
    bd即 borderwidth 用来指定 Label 控件的边框宽度,单位为像素,默认为 2 个像素
    bitmap指定显示在 Label 控件上的位图,若指定了 image 参数,则该参数会被忽略
    compound控制 Lable 中文本和图像的混合模式,若选项设置为 CENTER,则文本显示在图像上,如果将选项设置为 BOTTOM、LEFT、RIGHT、TOP,则图像显示在文本旁边。
    cursor指定当鼠标在 Label 上掠过的时候,鼠标的的显示样式,参数值为 arrow、circle、cross、plus
    disableforeground指定当 Label 设置为不可用状态的时候前景色的颜色
    font指定 Lable 中文本的 (字体,大小,样式)元组参数格式,一个 Lable 只能设置一种字体
    fg设置 Label 的前景色
    height/width设置 Lable 的高度/宽度,如果 Lable 显示的是文本,那么单位是文本单元,如果 Label 显示的是图像,那么单位就是像素,如果不设置,Label 会自动根据内容来计算出标签的高度
    highlightbackground当 Label 没有获得焦点的时候高亮边框的颜色,系统的默认是标准背景色
    highlightcolor指定当 Lable 获得焦点的话时候高亮边框的颜色,系统默认为0,不带高亮边框
    image指定 Label 显示的图片,一般是 PhotoImage、BitmapImage 的对象
    justify表示多行文本的对齐方式,参数值为 left、right、center,注意文本的位置取决于 anchor 选项
    padx/padypadx 指定 Label 水平方向上的间距(即内容和边框间),pady 指定 Lable 水平方向上的间距(内容和边框间的距离)
    relief指定边框样式,默认值是 “flat”,其他参数值有 “groove”、“raised”、“ridge”、“solid"或者"sunken”
    state该参数用来指定 Lable 的状态,默认值为"normal"(正常状态),其他可选参数有"active"和"disabled
    takefocus默认值为False,如果是 True,表示该标签接受输入焦点
    text用来指定 Lable 显示的文本,注意文本内可以包含换行符
    underline给指定的字符添加下划线,默认值为 -1 表示不添加,当设置为 1 时,表示给第二个文本字符添加下划线。
    wraplength将 Label 显示的文本分行,该参数指定了分行后每一行的长度,默认值为 0
    1. Label控件构成
      一个控件主要由背景和前景两部分组成。其中背景由三部分构成分别是内容区域、填充区、边框,这三个区域的大小通过以下属性进行控制,如下所示:

    width/height
    padx/pady
    borderwidth

    下面通过一个示意图对 Label 背景的区域构成进行说明:

    在这里插入图片描述

    图1:Label控件组成

    边框的宽度可以通过 borderwidth 来调整,其样式可以通过relief来设置(默认为平的 flat);填充区的大小调整分为水平方向和垂直方向,可以使用padx和pady来调整;内容区则主要用来显示文字或者图片,其大小由 width/height 来控制。

    下面看一组简单的示例,代码如下所示:

    import tkinter as tk
    win = tk.Tk()
    win.title("Python学习")
    win.geometry('400x200')
    win.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
    # 若内容是文字则以字符为单位,图像则以像素为单位
    label = tk.Label(win, text="Python学习",font=('宋体',20, 'bold italic'),bg="#7CCD7C",
                     # 设置标签内容区大小
                     width=30,height=5,
                     # 设置填充区距离、边框宽度和其样式(凹陷式)
                     padx=10, pady=15, borderwidth=10, relief="sunken")
    label.pack()
    win.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. 标签添加背景图
      Label(标签)除了可以显示文本之外,还可以用来显示图片,通过一组示例做简单的说明,代码如下所示:
    import tkinter as  tk
    win = tk.Tk()
    win.title("Python学习")
    win.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
    #显示图片(注意这里默认支持的图片格式为GIF)
    photo = tk.PhotoImage(file = 'C:/Users/Administrator/Desktop/python.gif')
    print(type(photo))
    # 将图片放在主窗口的右边
    lab =tk.Label(win,image=photo).pack(side="right")
    # 显示文字,设置文本格式
    text = "欢迎学习Python,\n"\
           "这里有精彩的教程,\n "\
           "这里有数不尽的知识宝藏"
    lab_text =tk.Label(win,text=text,fg ='#7CCD7C',font=('微软雅黑',15,'italic'),justify='left',padx=10).pack(side='left')
    win.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    注意:不同的 TK 版本所支持的图片格式也不完全相同,通过对上述示例的测试,此处只支持显示 GIF 格式的图片。

    1. Message控件
      Message 控件与 Label 控件的功能类似,它主要用来显示多行不可编辑的文本信息,与 Label 的不同之处在于该控件增加了自动分行的功能。下面对它做简单的介绍,示例如下:
    from tkinter import *
    #创建主窗口
    win = Tk()
    win.config(bg='#8DB6CD')
    win.title("Python学习")
    win.geometry('400x300')
    win.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
    txt = "学习Python,乐在其中"
    msg = Message (win, text=txt,width =60,font=('微软雅黑',10,'bold'))
    msg .pack (side=LEFT)
    #开始程序循环
    win .mainloop ()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.2.3 Button按钮

    Button 控件是 Tkinter 中常用的窗口部件之一,同时也是实现程序与用户交互的主要控件。通过用户点击按钮的行为来执行回调函数,是 Button 控件的主要功用。首先自定义一个函数或者方法,然后将函数与按钮关联起来,最后,当用户按下这个按钮时,Tkinter 就会自动调用相关函数。

    按钮控件使用起来非常简单,它同样可以包含文本、图像、位图,并通过command参数回调函数。当然按钮也并非一定要执行回调函数(callback function),它也只可以当一个“摆设”,不过这样的按钮是没有“灵魂的”,Button 控件的使用流程如下所示:

    import tkinter as tk
    # 创建窗口
    window =tk.Tk()
    # 设置回调函数
    def callback():
        print ("click me!")
    # 使用按钮控件调用函数
    b = tk.Button(window, text="点击执行回调函数", command=callback).pack()
    # 显示窗口
    tk.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Button 控件的常营属性如下所示:

    属性说明
    anchor控制文本所在的位置,默认为中心位置(CENTER)
    activebackground当鼠标放在按钮上时候,按妞的背景颜色
    activeforeground当鼠标放在按钮上时候,按钮的前景色
    bd按钮边框的大小,默认为 2 个像素
    bg按钮的背景色
    command用来执行按钮关联的回调函数。当按钮被点击时,执行该函数
    fg按钮的前景色
    font按钮文本的字体样样式
    height按钮的高度
    highlightcolor按钮控件高亮处要显示的颜色
    image按钮上要显示的图片
    justify按钮显示多行文本时,用来指定文本的对齐方式,参数值有 LEFT/RIGHT/CENTER
    padx/padypadx 指定 x 轴(水平方向)的间距大小,pady 则表示 y轴(垂直方向)的间距大小
    ipadx/ipady ipadx指标签文字与标签容器之间的横向距离;ipady 则表示标签文字与标签容器之间的纵向距离
    state设置按钮的可用状态,可选参数有NORMAL/ACTIVE/DISABLED,默认为 NORMAL
    text按钮控件要显示的文本

    除了 Button 按钮之外,和其类似的按钮还有复选框按钮(Checkbutton)和单选框按钮(Radiobutton),它们分别有着不同语法和使用场景,后续会做详细介绍。

    下面通过一组示例对 Button 控件的用法做简单的说明:

    import tkinter as tk
    from tkinter import messagebox
    window = tk.Tk()
    # 设置窗口的标题
    window.title('Python学习')
    # 设置并调整窗口的大小、位置
    window.geometry('400x300+300+200')
    # 当按钮被点击的时候执行click_button()函数
    def click_button():
        # 使用消息对话框控件,showinfo()表示温馨提示
        messagebox.showinfo(title='温馨提示', message='欢迎学习Python')
    # 点击按钮时执行的函数
    button = tk.Button(window,text='点击前往',bg='#7CCD7C',width=20, height=5,command=click_button).pack()
    # 显示窗口
    window.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    通过上述示例不难看出,Button 控件的作用就是“执行一个函数”,当用户点击按钮时会弹出一个新的对话框,这种操作巧妙地提升了用户的人机交互体验。因此,按钮控件在 GUI 编程中被广泛的使用。

    下面为 Button 控件添加一张背景图片,实现代码如下所示:

    import tkinter as tk
    from tkinter import messagebox
    window = tk.Tk()
    # 设置窗口的标题
    window.title('Python学习')
    # 设置窗口的大小
    window.geometry('400x300+300+200')
    # 当按钮被点击的时候执行click_button()函数
    def click_button():
        # 使用消息对话框控件,showinfo()表示温馨提示
        messagebox.showinfo(title='温馨提示', message='欢迎学习Python')
    # 创建图片对象
    im = tk.PhotoImage(file='C:/Users/Administrator/Desktop/按钮.gif')
    # 通过image参数传递图片对象
    button = tk.Button(window,image=im,command=click_button).pack()
    # 启动窗口
    window.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    扩展:按钮的布局
    按钮在主窗口中的布局,通常使用 grid() 函数来完成,该函数以网格状的形式(即行和列)来管理窗口的布局。

    grid() 布局管理器提供了一个sticky参数,通过该参数可以设置按钮的方位,该参数默认将控件设置居中,其他参数值有 N/S/W/E(上/下/左/右),而且可以组合在一起使用,比如 NW/WE/SE/SW/NE 等,这与anchor参数控制文本的显示位置,有着异曲同工之妙。
    值得大家注意的是 grid() 布局方法不能与 pack() 混合在一起使用,相关知识在后续内容中还会做针对性讲解。

    下面看一组简单的示例:

    import tkinter as tk
    from tkinter import messagebox
    win = tk.Tk()
    win.title("Python学习")
    win.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
    win.geometry('400x200+100+100')
    win.resizable(0,0)
    # 将俩个标签分别布置在第一行、第二行
    tk.Label(win, text="账号:").grid(row=0)
    tk.Label(win, text="密码:").grid(row=1)
    # 创建输入框控件
    e1 = tk.Entry(win)
    # 以 * 的形式显示密码
    e2 = tk.Entry(win,show='*')
    e1.grid(row=0, column=1, padx=10, pady=5)
    e2.grid(row=1, column=1, padx=10, pady=5)
    # 编写一个简单的回调函数
    def login():
        messagebox.showinfo('欢迎您到来')
    # 使用 grid()的函数来布局,并控制按钮的显示位置
    tk.Button(win, text="登录", width=10, command=login).grid(row=3, column=0, sticky="w", padx=10, pady=5)
    tk.Button(win, text="退出", width=10, command=win.quit).grid(row=3, column=1, sticky="e", padx=10, pady=5)
    win.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2.2.4 Entry输入和Text输入

    2.2.4.1 Entry输入组件&Spinbox高级输入

    Entry 控件是 Tkinter GUI 编程中的基础控件之一,它的作用就是允许用户输入内容,从而实现 GUI 程序与用户的交互,比如当用户登录软件时,输入用户名和密码,此时就需要使用 Entry 控件。

    Entry 控件使用起来非常简单,下面对该控件做简单的介绍。基本语法格式如下:

    tk_entry = Entry( master, option, ... )
    
    • 1

    基本属性
    Entry 控件除了具备一些共有属性之外,还有一些自身的特殊属性,如下表所示:

    属性名称说明
    exportselection默认情况下,如果在输入框中选中文本会复制到粘贴板,如果要忽略这个功能,可以设置为 exportselection=0
    selectbackground选中文字时的背景颜色
    selectforeground选中文字时的前景色
    show指定文本框内容以何种样式的字符显示,比如密码可以将值设为 show=“*”
    textvariable输入框内值,也称动态字符串,使用 StringVar() 对象来设置,而 text 为静态字符串对象
    xscrollcommand设置输入框内容滚动条,当输入的内容大于输入框的宽度时使用

    前面我们已经讲过Variable类,它的子类就是动态数据类型。与testvariable属性配合用于实时跟踪输入的变化。
    下面通过一个时钟示例对“动态字符串”做进一步了解,代码如下:

    import tkinter as tk
    import time
    root = tk.Tk()
    root.title("动态数据类型-时钟")
    root.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
    root.geometry('450x150+100+100')
    root.resizable(0,0)
    # 获取时间的函数
    def gettime():
        # 获取当前时间
        dstr.set(time.strftime("%H:%M:%S"))
        # 每隔 1s 调用一次 gettime()函数来获取时间
        root.after(1000, gettime)
    # 生成动态字符串
    dstr = tk.StringVar()
    # 利用 textvariable 来实现文本变化
    lb = tk.Label(root,textvariable=dstr,fg='green',font=("微软雅黑",85))
    lb.pack()
    # 调用生成时间的函数
    gettime()
    # 显示窗口
    root.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    除了一些基本的属性之外,Entry 控件还提供了一些常用的方法,如下所示:

    方法说明
    delete()根据索引值删除输入框内的值
    get()获取输入框内的值
    set()设置输入框内的值
    insert()在指定的位置插入字符串
    index()返回指定的索引值
    select_clear()取消选中状态
    select_adujst()确保输入框中选中的范围包含 index 参数所指定的字符,选中指定索引和光标所在位置之前的字符
    select_from (index)设置一个新的选中范围,通过索引值 index 来设置
    select_present()返回输入框是否有处于选中状态的文本,如果有则返回 true,否则返回 false。
    select_to()选中指定索引与光标之间的所有值
    select_range()选中指定索引与光标之间的所有值,参数值为 start,end,要求 start 必须小于 end。

    注意:在 Entry 控件中,我们可以通过以下方式来指定字符的所在位置:

    • 数字索引:表示从 0 开始的索引数字;
    • “ANCHOE”:在存在字符的情况下,它对应第一个被选中的字符;
    • “END”:对应已存在文本中的最后一个位置;
    • "insert(index,‘字符’):将字符插入到 index 指定的索引位置。

    示例如下:

    import tkinter as tk
    win = tk.Tk()
    # 设置主窗口
    win.geometry('250x100')
    win.resizable(0,0)
    # 创建输入框控件
    entry1 = tk.Entry(win)
    # 放置输入框,并设置位置
    entry1.pack(padx=20, pady=20)
    entry1.delete(0, "end")
    # 插入默认文本
    entry1.insert(0,'Python学习')
    # 得到输入框字符串
    print(entry1.get())
    # 删除所有字符
    # entry1.delete(0, tk.END)
    win.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    认识完 Entry 控件的基本属性和常用方法后,下面我看一组简单的示例:

    import tkinter as tk
    win =tk.Tk()
    # 设置主窗口
    win.geometry('250x100')
    win.resizable(0,0)
    # 新建文本标签
    labe1 = tk.Label(win,text="账号:")
    labe2 = tk.Label(win,text="密码:")
    # grid()控件布局管理器,以行、列的形式对控件进行布局,后续会做详细介绍
    labe1.grid(row=0)
    labe2.grid(row=1)
    # 为上面的文本标签,创建两个输入框控件
    entry1 = tk.Entry(win)
    entry2 = tk.Entry(win)
    # 对控件进行布局管理,放在文本标签的后面
    entry1.grid(row=0, column=1)
    entry2.grid(row=1, column=1)
    # 显示主窗口
    win.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    GUI 界面可以说真的很“简陋”,其实一款界面美观的 GUI 程序会受到诸多因素影响,比如距离调整、样式设置等等

    Entry 控件也提供了对输入内容的验证功能,比如要求输入英文字母,你却输入了数字,这就属于非法输入,Entry 控件通过以下参数实现对内容的校验:

    参数说明
    validate指定验证方式,字符串参数,参数值有 focus、focusin、focusout、key、all、none。
    validatecommand指定用户自定义的验证函数,该函数只能返回 True 或者 Fasle
    invalidcommand当 validatecommand 指定的验证函数返回 False 时,可以使用该参数值再指定一个验证函数。

    下面对 validate 的参数值做简单的介绍:

    参数值说明
    focus当 Entry 组件获得或失去焦点的时候验证
    focusin当 Entry 组件获得焦点的时候验证
    focuson当 Entry 组件失去焦点的时候验证
    key当输入框被编辑的时候验证
    all当出现上边任何一种情况的时候验证
    none默认不启用验证功能,需要注意的是这里是字符串的 ‘none’

    下面看一组具体的运行示例:

    import tkinter as tk
    from tkinter import messagebox
    win = tk.Tk()
    # 设置主窗口
    win.geometry('250x200+250+200')
    win.resizable(0,0)
    # 创建验证函数
    def check():
        if entry1.get() == "Python":
            messagebox.showinfo("输入正确")
            return True
        else:
            messagebox.showwarning("输入不正确")
            entry1.delete(0,tk.END)
            return False
    # 新建文本标签
    labe1 = tk.Label(win,text="账号:")
    labe2 = tk.Label(win,text="密码:")
    labe1.grid(row=0)
    labe2.grid(row=1)
    # 创建动字符串
    Dy_String = tk.StringVar()
    # 使用验证参数 validata,参数值为 focusout 当失去焦点的时候,验证输入框内容是否正确
    entry1 = tk.Entry(win,textvariable =Dy_String,validate ="focusout",validatecommand=check)
    entry2 = tk.Entry(win)
    # 对控件进行布局管理,放在文本标签的后面
    entry1.grid(row=0, column=1)
    entry2.grid(row=1, column=1)
    win.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    不仅如此,Tkinter 还为验证函数提供一些额外的选项,不过想要使用这些额外选项,需要提前使用 register() 方法对验证函数进行注册,。常用的选项如下所示:

    选项说明
    %d有 3 个参数值,其中 0 表示删除操作;1 表示插入操作;2 表示获得、失去焦点或 textvariable 变量的值被修改
    %i当用户进行插入或者删除操作的时,该选项值是插入或者删除的索引位置,若是其他的情况则选项值为 -1
    %P该选项值指定了输入框内的文本内容,只有当输入框的值允许改变的时候,该选项值才会生效。
    %s改值为调用验证函数前输入框内的文本内容
    %S该选项值,只有插入或者删除操作触发验证函数的时候才会生效,它表示了被删除或者插入的内容
    %v表示当前 Entry 控件的 validate 参数的值
    %V表示触发验证函数的原因,值为 focus、focusin 、focusout、all、key… 中的一个。
    %W该选项表示控件类型,即控件的名字(Entry)

    下面看一组见简单的示例应用:

    import tkinter as tk
    from tkinter import messagebox
    win = tk.Tk()
    # 设置主窗口
    win.geometry('250x200+250+200')
    win.resizable(0,0)
    # 新建文本标签
    labe1 = tk.Label(win,text="账号:")
    labe2 = tk.Label(win,text="密码:")
    labe1.grid(row=0)
    labe2.grid(row=1)
    # 创建动字符串
    Dy_String = tk.StringVar()
    # 创建验证函数
    def check(strings,reason, id):
        if entry1.get() == "Python":
            messagebox.showinfo("输入正确")
            print(strings,reason,id)
            return True
        else:
            messagebox.showwarning("输入不正确")
            print(strings,reason,id)
            return False
    # 对验证函数进行注册
    CheckTest = win.register(check)
    # 使用验证参数 validata,参数值为 focusout 当失去焦点的时验证输入框内容是否正确
    entry1 = tk.Entry(win,textvariable =Dy_String,validate ="focusout",validatecommand=(CheckTest,'%P','%V','%W'))
    entry2 = tk.Entry(win)
    # 对控件进行布局管理,放在文本标签的后面
    entry1.grid(row=0, column=1)
    entry2.grid(row=1, column=1)
    win.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    实例演示
    下面看一组实例演示,通过实现一个简单的计算器小程序来对 Entry 控件做进一步说明:

    from tkinter import *
    # 创建窗体
    win = Tk()
    win.geometry('300x300')
    # 创建一个容器来包括其他控件
    frame = Frame (win)
    # 创建一个计算器
    def calc() :
    # 用户输入的表达式,计算结果后转换为字符串
        result = "= "+ str (eval(expression.get()))
        #将计算的结果显示在Label控件上
        label.config(text =result)
    #创建一个Label控件
    label = Label (frame)
    #创建一个Entry控件
    entry = Entry (frame)
    #读取用户输入的表达式
    expression = StringVar ()
    #将用户输入的表达式显示在Entry控件上
    entry ["textvariable"] = expression
    #创建-一个 Button控件.当用户输入完毕后,单击此按钮即计算表达式的结果
    button1 = Button (frame, text="等 于",command=calc)
    #设置Entry控件为焦点所在
    entry.focus ()
    frame.pack ()
    #Entry控件位于窗体的上方
    entry .pack()
    #Label控件位于窗体的左方
    label .pack (side="left")
    #Button控件位于窗体的右方
    button1.pack (side="right")
    #开始程序循环
    frame .mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    2.2.4.2 Spinbox 高级输入框

    Spinbox 是 Entry 控件的升级版,它是 Tkinter 8.4 版本后新增的控件,该控件不仅允许用户直接输入内容,还支持用户使用微调选择器(即上下按钮调节器)来输入内容。在一般情况下,Spinbox 控件用于在固定的范围内选取一个值的时候使用。它类似于Combobox组件,但Spinbox不会展开下拉列表供用户选择,Spinbox只能通过向上、向下的小箭头来选择不同的选项。
    在使用Spinbox组件时,既可以通过from(由于from是关键字,实际使用时写成from_,指定选项开始值),to(结束值),increment(步长)选项来指定选项数字列表,也可通过values选项来指定多个列表项,该选项的值可以是list或tuple。
    同样的,textvariable、command选项同样生效,当用户点击Spinbox的箭头时,程序会触发command选项指定的事件处理函数。

    下面看一组简单的应用示例:

    from tkinter import *
    from tkinter import ttk
    class App:
        def __init__(self,master)
            self.master = master
            self.initWidgets()
        def initWidgets(self):
            ttk.Lable(self.master,text='指定from_\to\increment').pack()
            #说明标签1
            sb1 = Spinbox(self.master,from_=20,to=100,increment=5)
            sb1.pack(fill=X,expand=YES)
            #建立指定开始结束位的Spinbox输入框
            ttk.Lable(self.master,text='指定values').pack()
            #说明标签2
            sb2 = Spinbox(self.master,values=('Python','C','C++','JAVA'),command=self.press)
            sb2.pack(fill=X,expand=YES)
            #建立指定元素列表的Spinbox输入框
            ttk.Lable(self.master,text='绑定变量').pack()
            #说明标签3
            self.intVar = IntVar()
            sb3 = Spinbox(self.master,values=list(range(20.100,5)),textvariable=self.intVar,command=self.press)
            sb3.pack(fill=X,expand=YES)
            self.intVar.set(33)
        def press(self)
            print(self.sb2.get())
    root = Tk()
    root.title('Spinbox测试')
    App(root)
    root.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    2.2.4.3 Text输入组件

    Text 文本控件是 Tkinter 中经常使用的控件,与 Entry 控件相比,Text 控件用于显示和编辑多行文本,而 Entry 控件则适合处理单行文本。

    Text 控件类似 HTML 中的标签,允许用户以不同的样式、属性来显示和编辑文本,它可以包含纯文本或者格式化文本,同时支持嵌入图片、显示超链接以及带有 CSS 格式的 HTML 等。Text 控件的有很多的适用场景,比如显示某个产品的详细信息,或者人物介绍等。下面我们对 Text 控件属性和常用方法做简单的介绍。

    1. 基本属性
      除了基本的共有属性之外,Text 控件还具备以下属性:
    属性说明
    autoseparators默认为 True,表示执行撤销操作时是否自动插入一个“分隔符”(其作用是用于分隔操作记录)
    exportselection默认值为 True,表示被选中的文本是否可以被复制到剪切板,若是 False 则表示不允许。
    insertbackground设置插入光标的颜色,默认为 BLACK
    insertborderwidth设置插入光标的边框宽度,默认值为 0
    insertofftime该选项控制光标的闪烁频频率(灭的状态)
    insertontime该选项控制光标的闪烁频频率(亮的状态)
    selectbackground指定被选中文本的背景颜色,默认由系统决定
    selectborderwidth指定被选中文本的背景颜色,默认值是0
    selectforeground指定被选中文本的字体颜色,默认值由系统指定
    setgrid默认值是 False,指定一个布尔类型的值,确定是否启用网格控制
    spacing1指定 Text 控件文本块中每一行与上方的空白间隔,注意忽略自动换行,且默认值为 0。
    spacing2指定 Text 控件文本块中自动换行的各行间的空白间隔,忽略换行符,默认值为0
    spacing3指定 Text 组件文本中每一行与下方的空白间隔,忽略自动换行,默认值是 0
    tabs定制 Tag 所描述的文本块中 Tab 按键的功能,默认被定义为 8 个字符宽度,比如 tabs=(‘1c’, ‘2c’, ‘8c’) 表示前 3 个 Tab 宽度分别为 1厘米,2厘米,8厘米。
    undo该参数默认为 False,表示关闭 Text 控件的“撤销”功能,若为 True 则表示开启
    wrap该参数用来设置当一行文本的长度超过 width 选项设置的宽度时,是否自动换行,参数值 none(不自动换行)、char(按字符自动换行)、word(按单词自动换行)
    xscrollcommand该参数与 Scrollbar 相关联,表示沿水平方向上下滑动
    yscrollcommand该参数与 Scrollbar 相关联,表示沿垂直方向左右滑动
    1. 基本方法
      Text 中的方法有几十个之多,这里不进行一一列举,主要对常用的方法进行介绍,如下表所示:
    方法说明
    bbox(index)返回指定索引的字符的边界框,返回值是一个 4 元组,格式为(x,y,width,height)
    edit_modified()该方法用于查询和设置 modified 标志(该标标志用于追踪 Text 组件的内容是否发生变化)
    edit_redo()“恢复”上一次的“撤销”操作,如果设置 undo 选项为 False,则该方法无效。
    edit_separator()插入一个“分隔符”到存放操作记录的栈中,用于表示已经完成一次完整的操作,如果设置 undo 选项为 False,则该方法无效。
    get(index1, index2)返回特定位置的字符,或者一个范围内的文字。
    image_cget(index, option)返回 index 参数指定的嵌入 image 对象的 option 选项的值,如果给定的位置没有嵌入 image 对象,则抛出 TclError 异常
    image_create()在 index 参数指定的位置嵌入一个 image 对象,该 image 对象必须是 Tkinter 的 PhotoImage 或 BitmapImage 实例。
    insert(index, text)在 index 参数指定的位置插入字符串,第一个参数也可以设置为 INSERT,表示在光标处插入,END 表示在末尾处插入。
    delete(startindex [, endindex])删除特定位置的字符,或者一个范围内的文字。
    see(index)如果指定索引位置的文字是可见的,则返回 True,否则返回 False。

    下面先看一组简单的实例介绍,实例如下所示:

    from tkinter import *
    win = Tk()
    win.title("Python")
    win.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
    win.geometry('400x420')
    # 创建一个文本控件
    # width 一行可见的字符数;height 显示的行数
    text = Text(win, width=50, height=30, undo=True, autoseparators=False)
    # 适用 pack(fill=X) 可以设置文本域的填充模式。比如 X表示沿水平方向填充,Y表示沿垂直方向填充,BOTH表示沿水平、垂直方向填充
    text.pack()
    # INSERT 光标处插入;END 末尾处插入
    text.insert(INSERT, 'Python,一种很火的编程语言')
    win.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    上述代码中 Text 控件通过 heigt 和 width 参数来控制文本域的大小(即纸张大小),当然您也可以将其设置为自适用模式,即不设置具体的文本域大小。

    下面定义上述代码做一下稍微改动,为其增加“撤销”和“恢复”的功能,代码如下所示:

    from tkinter import *
    win = Tk()
    win.title("Python")
    win.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
    win.geometry('400x300')
    # 创建一个文本控件
    # width 一行可见的字符数;height 显示的行数
    text = Text(win, width=50, height=20, undo=True, autoseparators=False)
    text.grid()
    # INSERT 光标处插入;END 末尾处插入
    text.insert(INSERT, 'python,一种很火的编程语言')
    # 定义撤销和恢复方法,调用edit_undo()和 edit_redo()方法
    def backout():
        text.edit_undo()
    def regain():
        text.edit_redo()
    # 定义撤销和恢复按钮
    Button(win,text = '撤销',command = backout).grid(row=3, column=0, sticky="w", padx=10, pady=5)
    Button(win,text = '恢复',command = regain).grid(row=3, column=0, sticky="e", padx=10, pady=5)
    win.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    注意:点击“撤销”按钮后输入的所有语句都会被删除,如果再点击“恢复”按钮,刚刚删除的内容又会恢复。
    文本控件(Text)支持三种类型的特殊结构,即 Mark、Tag 以及 Index,每一种结构都有相应的方法,下面对这些结构做相关的介绍。

    1. Index文本索引
      Index 索引,用于指定字符在文本中的真实位置,这与我们经常使用 Python 索引是一样的,不过在 Text 文本控件中,两者之间的使用形式存在一些差异。

    Tkinter 提供以下文本索引类型,如下表所示:

    索引类型说明
    INSERT对应插入光标的位置
    CURRENT对应与鼠标坐标最接近的位置
    END对应 Text 控件的文本域中最后一个字符的下一个位置
    “line.column”表示某一行某一列的一个位置,比如 1.2 表示第一行第二列的一个位置
    “line.end”表示某一行到末尾的最后一个位置
    SEL一种针对于 Tag 的特殊索引用法,(SEL_FIRST,SEL_LAST) 表示当前被选中的范围

    下面看一组示例了解 Index 的使用方法:

    from tkinter import *
    root = Tk()
    root.title("Python")
    root.geometry('400x200')
    root.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
    text =Text(root, width=35, heigh=15)
    text.pack()
    # 在文本域中插入文字
    text.insert(INSERT, 'python')
    # 继续向后插入文字
    text.insert("insert", ",I love Python")
    # 获取字符,使用get() 方法
    print(text.get("1.3", "1.end"))
    # 显示窗口
    root.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. Tag文本标签
      Tag(标签)用来给一定范围内的文字起一个标签名,通过该标签名就能操控某一范围内的文字,比如修改文本的字体、尺寸和颜色。除此之外,该标签还可以和事件函数绑定在一起使用。
      这里需要注意,Tags 的名字是由字符串组成的,但不能是空白字符串。

    Tag 提供了一些常用的方法,通过这些方法可以操作 Tag(标签),常用方法如下:

    |方法 |说明|
    |tag_add(tagName,index1,index2) |为指定索引范围内的内容添加一个标签名字,如果 index2 不存在,则单独为 Index1 指定的内容添加 Tag|
    |tag_bind(tagName, sequence, func, add=None)| 为 Tag 绑定事件,解除绑定使用 tag_unbind() 方法|
    |tag_cget(tagName,option)| 返回 tagName 指定的 option 选项的值|
    |tag_configure(tagName, cnf=None, **kw) |设置 tagName 的选项|
    |tag_delete(tagNames)| 删除单个或者多个 tagNames 指定的标签|
    |tag_lower(tagName, belowThis=None) |降低 Tag 的优先级,如果 belowThis 参数不为空,则表示 tagName 需要比 belowThis 指定的 Tag 优先级更低|
    |tag_names(index=None) |如果不带参数,表示返回 Text 组件中所有 Tags 的名字,若存在 index 参数则返回该位置上所有 Tags 的名字|
    |tag_nextrange(tagName, index1, index2=None) |在 index1 到 index2 的范围内第一个 tagName 的位置,若不存在则返回空字符串。|
    |tag_raise(tagName, aboveThis=None) |提高 Tag 的优先级,如果 aboveThis 参数不为空,则表示 tagName 需要比 aboveThis 指定的 Tag 优先级更高|
    |tag_ranges(tagName) |返回所有 tagName 指定的文本,并将它们的范围以列表的形式返回|
    |tag_remove(tagName, index1, index2=None)| 删除 index1 到 index2 之间所有的 tagName,如果忽略 index2 参数,那么只删除 index1 指定字符的 tagName|

    下面针对上述属性和方法看一组简单的示例:

    from tkinter import *
    # 创建多行文本框控件
    from tkinter import *
    # 创建主窗口
    win = Tk()
    win.title(string = "Python")
    # 创建一个Text控件
    text = Text (win)
    # 在Text控件内插入- -段文字 ,INSERT表示在光标处插入,END表示在末尾处插入
    text.insert (INSERT,  "python,一种很火的编程语言\n\n")
    # 跳下一行
    text.insert (INSERT, "\n\n")
    # 在Text控件内插入- -个按钮
    button = Button(text, text="关闭",command=win.quit)
    text. window_create (END, window=button)
    # 填充水平和垂直方向,这里设置 expand为 True 否则不能垂直方向延展
    text .pack (fill=BOTH,expand=True)
    # 在第一行文字的第0个字符到第6个字符处插入标签,标签名称为"name"
    text.tag_add("name", "1.0", "1.6")
    # 将插入的按钮设置其标签名为"button"
    text.tag_add ("button", button)
    #使用 tag_config() 来改变标签"name"的前景与背景颜色,并加下画线,通过标签控制字符的样式
    text.tag_config("name", font=('微软雅黑',18,'bold'),background="yellow", foreground= "blue",underline=1)
    #设置标签"button"的居中排列
    text. tag_config("button", justify="center")
    #开始程序循环
    win .mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    1. Mark文本标记
      Mark(标记)通常被用来当作书签,它可以帮助用户快速找到内容的指定位置,并且跟随相应的字符一起移动。

    Mark 有两种类型的标记,分别是“INSERT”和“CURRENT”,其含义如下:

    • INSERT:指定当前插入光标的位置,Tkinter 会在该位置绘制一个闪烁的光标;
    • CURRENT:用于指定当前光标所处坐标最邻近的位置。

    它们是 Tkinter 中预定义的标记,因此不能被删除。除此上述标记外,我们还可以通过 user-define marks(用户自定义标记) 的方式来自定义 Mark。Tkinter 也提供了一些有关 Mark 的常用的方法,如下所示:

    方法说明
    mark_gravity(markName, direction=None)设置 Mark 的移动方向,默认是 “right”,也可以设置为 “left” ,表示即如果在 Mark 处插入文本的话,Mark 的标记移动方向,也就是文本的插入方向。
    mark_names()返回 Text 组件中所有 Marks 的名字
    mark_next(index)返回在 index 指定的位置后边的一个 Mark 的名字
    mark_previous(index)返回在 index 指定的位置前边的一个 Mark 的名字
    mark_set(markName, index)移动 Mark 到 index 参数指定的位置,如果 markName 参数指定的 Mark 不存在,则创建一个新的 Mark
    mark_unset(MarkName)删除指定的 Mark

    注意:如果在 Mark 标记的位置之前插入或删除文本,那么 Mark 跟着一起移动。如果要删除 Mark 需要使用 mark_unset() 方法,但是只会删除 Mark 周围的文本,并不会删除 Mark 标记本身。

    下面看一组简单的实例:

    import tkinter as tk
    root = tk.Tk()
    root.title("Python")
    root.geometry('400x200')
    root.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
    text = tk.Text(root, width=35, heigh=15)
    text.pack()
    text.insert("insert", "python")
    # 设置标记,这里的 1.end 表示 第一行最后一个字符,当然也可以使用数字来表示比如 1.5 表示第一行第五个字符
    text.mark_set("name", "1.end")
    # 在标记之后插入相应的文字
    text.insert("name", ",网址:https://editor.csdn.net/")
    # 跟着自动移动,往后插入,而不是停留在原位置
    text.insert("name", ",欢迎光临")
    # 若使用 mark_unset() 可以删除指定的标记
    # text.mark_unset("name")
    # 但使用delete来清除所有的内容, mark 标记依旧会存在
    # text.delete("1.0","end")
    # 依然可以使用 name标记来插入
    # text.insert("name", "Python答疑")
    # 显示窗口
    root.mainloop()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    由于篇幅的原因,我们在下一节介绍剩余的组件。

  • 相关阅读:
    浅读一下dotenv的主干逻辑的源码
    C++11 --- 浅谈静态成员
    html属性值可以不用引号吗,实例验证
    西安电子科技大学软件体系结构复习
    WPF 稳定的全屏化窗口方法
    websocket实现实时变化图表内容
    pycharm快捷键大全
    多线程(虚拟地址空间)
    Springboot毕设项目基于SpringBoot的演唱会购票系统z2673(java+VUE+Mybatis+Maven+Mysql)
    点云拟合平面原理和实现(Halcon)
  • 原文地址:https://blog.csdn.net/aalen86/article/details/126210278