《零基础入门学习Python》第069讲:GUI的终极选择:Tkinter6

前面我们已经学习了Tkinter 的好几个组件。绘制单行文本我们当然知道要使用 Label 组件,多行选项我们使用 Listbox 组件,输入框用 Entry 组件,Button 就是按钮,Radiobutton 和 Checkbutton 分别对应单选和多选的情况,然后呢,有多个组件,我们还可以使用 Frame 和 LabelFrame 把它们构成一个框架,之后我们还学习了两个会滚的组件:Scrollbar 和 Scale,Scrollbar 就是滚动条,Scale 就是提供一个范围,让用户在这个范围内选择一个确切的值。

今天我们继续学习一个新的组件:Text组件。这个组件主要是用于显示和处理多行文本,那么在tkinter的所有组件中,Text 组件显得异常强大和灵活,适用于多种任务。虽然说这个组件的主要任务是用于显示多行文本,但是它常常被用于当做简单的文本处理器、文本编辑器或者网页浏览器来使用,例如我们的IDLE的输入框,就是Text组价构成的。

我们举个例子来演示一下:

 
  
  1. import tkinter as tk

  2. root = tk.Tk()

  3. text = tk.Text(root, width = 30, heigh = 2)

  4. text.pack()

  5. text.insert("insert", "I love \n")

  6. text.insert("end", "Python.com")

  7. root.mainloop()

运行一下:

我们可以对这个文本内容进行任意的操作。

Text 组价不仅支持插入和编辑文本,还支持插入 image 对象,或者前面介绍的组件,例如说你可以插入一个按钮

 
  
  1. import tkinter as tk

  2. root = tk.Tk()

  3. text = tk.Text(root, width = 30, heigh = 5)

  4. text.pack()

  5. text.insert("insert", "I love \n")

  6. text.insert("end", "Python.com!")

  7. def show():

  8. print("哪里不会点哪里")

  9. b1 = tk.Button(text, text = "点我啊", command = show)

  10. text.window_create("insert", window = b1)

  11. root.mainloop()

《零基础入门学习Python》第069讲:GUI的终极选择:Tkinter6_第1张图片

接下来插入图片试一下:

 
  
  1. import tkinter as tk

  2. root = tk.Tk()

  3. text = tk.Text(root, width = 30, heigh = 10)

  4. text.pack()

  5. photo = tk.PhotoImage(file = 'logo.gif')

  6. def show():

  7. text.image_create("end", image = photo)

  8. b1 = tk.Button(text, text = "点我啊", command = show)

  9. text.window_create("insert", window = b1)

  10. root.mainloop()

《零基础入门学习Python》第069讲:GUI的终极选择:Tkinter6_第2张图片

看到这里,你是不是觉得Text组件很强大呢?其实更牛的东西还在后头。我们接着来:

Indexes 用法

Indexes(索引)是用来指向 Text 组件中文本的位置,跟 Python 的序列索引一样,Text 组件索引也是对应实际字符之间的位置。

Tkinter 提供一系列不同的索引类型:

  • "line.column"(行/列)
  • "line.end"(某一行的末尾)
  • "insert"
  • "current"
  • "end"
  • user-defined marks
  • user-defined tags("tag.first","tag.last")
  • selection(SEL_FIRST,SEL_LAST)
  • window coordinate("@x,y")
  • embedded object name(window,images)
  • expressions

下边我们逐个给大家讲解:

"line.column"

由于我们的Text组件是支持多行文本的,所以我们现在从一个一维空间变成了二维空间,我们就可以用行和列来定位一个位置。

"%d.%d" % (line, column)

行/列 是最基础的索引方式,它们将索引位置的行号和列号以字符串的形式表示出来(中间以 "." 分隔,例如 "1.0")。需要注意的是,行号以 1 开始,列号则以 0 开始。

指定超出现有文本的最后一行的行号,或超出一行中列数的列号都不会引发错误。对于这样的指定,Tkinter 解释为已有内容的末尾的下一个位置。

需要注意的是,使用 行/列 的索引方式看起来像是浮点值。其实不只像而已,你在需要指定索引的时候使用浮点值代替也是可以的:

 
  
  1. import tkinter as tk

  2. root = tk.Tk()

  3. text = tk.Text(root, width = 30, heigh = 3)

  4. text.pack()

  5. text.insert("insert", "I love Python")

  6. print(text.get("1.2", 1.6))

  7. root.mainloop()

使用 index() 方法可以将所有支持的“索引”格式转换为“行/列”格式的索引号。

"line.end"

行号加上字符串 ".end" 的格式表示为该行最后一个字符的位置:

 
  
  1. text.insert("insert", "I love Python")

  2. print(text.get("1.2", "1.end"))

 
  
  1. >>>

  2. love Python

"insert"

对应插入光标的位置。

"current"

对应与鼠标坐标最接近的位置。不过,如果你紧按鼠标任何一个按钮,它会直到你松开它才响应。

 "end"

对应 Text 组件的文本缓冲区最后一个字符的下一个位置。

user-defined marks

user-defined marks 是对 Text 组件中位置的命名。"insert" 和 "current" 是两个预先命名好的 marks,除此之外你可以自定义 marks(请参考下方【Marks 用法】)。

User-defined tags

User-defined tags 代表可以分配给 Text 组件的特殊事件绑定和风格(请参考下节课的【Tags 用法】)。

你可以使用 "tag.first"(使用 tag 的文本的第一个字符之前)和 "tag.last"(使用 tag 的文本的最后一个字符之后)语法表示标签的范围。

 
  
  1. "%s.first" % tagname

  2. "%s.last" % tagname

如果查无此 tag,那么 Tkinter 会抛出一个TclError 异常。

selection(SEL_FIRST,SEL_LAST)

selection 是一个名为 SEL(或 "sel")的特殊 tag,表示当前被选中的范围,你可以使用  SEL_FIRST 到 SEL_LAST 来表示这个范围。如果没有选中的内容,那么 Tkinter 会抛出一个TclError 异常。

window coordinate("@x,y")

你还可以使用窗口坐标作为索引。例如在一个事件绑定中,你可以使用以下代码找到最接近鼠标位置的字符:

"@%d,%d" % (event.x, event.y)

embedded object name(window,images)

embedded object name 用于指向在 Text 组件中嵌入的 window 和 image 对象。要引用一个 window,只要简单地将一个 Tkinter 组件实例作为索引即可。引用一个嵌入的 image,只需使用相应的 PhotoImage 和 BitmapImage 对象。

expressions

expressions 用于修改任何格式的索引,用字符串的形式实现修改索引的表达式。

具体表达式实现如下:

表达式

含义

"+ count chars" 1. 将索引向前(->)移动 count 个字符
2. 可以越过换行符,但不能超过 END 的位置
"- count chars" 1. 将索引向后(<-)移动 count 个字符
2. 可以越过换行符,但不能超过 "1.0" 的位置
"+ count lines" 1. 将索引向前(->)移动 count 行
2. 索引会尽量保持与移动前在同一列上,但如果移动后的那一行字符太少,将移动到该行的末尾
"- count lines" 1. 将索引向后(<-)移动 count 行
2. 索引会尽量保持与移动前在同一列上,但如果移动后的那一行字符太少,将移动到该行的末尾
" linestart" 1. 将索引移动到当前索引所在行的起始位置
2. 注意,使用该表达式前边必须有一个空格隔开
" lineend" 1. 将索引移动到当前索引所在行的末尾
2. 注意,使用该表达式前边必须有一个空格隔开
" wordstart" 1. 将索引移动到当前索引指向的单词的开头
2. 单词的定义是一系列字母、数字、下划线或任何非空白字符的组合
3. 注意,使用该表达式前边必须有一个空格隔开
" wordend" 1. 将索引移动到当前索引指向的单词的末尾
2. 单词的定义是一系列字母、数字、下划线或任何非空白字符的组合
3. 注意,使用该表达式前边必须有一个空格隔开

TIPS:只要结果不产生歧义,关键字可以被缩写,空格也可以省略。例如:"+ 5 chars" 可以简写成 "+5c"

在实现中,为了确保表达式为普通字符串,你可以使用 str 或格式化操作来创建一个表达式字符串。下边例子演示了如何删除插入光标前边的一个字符:

 
  
  1. def backspace(event):

  2. event.widget.delete("%s-1c" % "insert", "insert")

Marks 用法

Marks(标记)通常是嵌入到 Text 组件文本中的不可见对象。事实上 Marks 是指定字符间的位置,并跟随相应的字符一起移动。Marks 有 "insert","current" 和 user-defined marks(用户自定义的 Marks)。其中,"insert" 和 "current" 是 Tkinter 预定义的特殊 Marks,它们不能够被删除。

"insert" 用于指定当前插入光标的位置,Tkinter 会在该位置绘制一个闪烁的光标(因此并不是所有的 Marks 都不可见)。

 "current" 用于指定与鼠标坐标最接近的位置。不过,如果你紧按鼠标任何一个按钮,它会直到你松开它才响应。

你还可以自定义任意数量的 Marks,Marks 的名字是由普通字符串组成,可以是除了空白字符外的任何字符(为了避免歧义,你应该起一个有意义的名字)。使用 mark_set() 方法创建和移动 Marks。

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

如果有做相关练习的,应该会被 Mark 的很多特性所疑惑,在准备这个内容的时候也很是迷惑,找了不知多少文档......最后总结为下边几个例子讲解:

例1,Mark 事实上就是索引,用于表示位置:

 
  
  1. import tkinter as tk

  2. root = tk.Tk()

  3. text = tk.Text(root, width = 30, heigh = 3)

  4. text.pack()

  5. text.insert("insert", "I love Python")

  6. text.mark_set("here", "1.2")

  7. text.insert("here", "插")

  8. root.mainloop()

 

例2,如果 Mark 前边的内容发生改变,那么 Mark 的位置也会跟着移动(说白了就是 Mark 会“记住”它后边的那货~):

 
  
  1. text.insert("insert", "I love Python")

  2. text.mark_set("here", "1.2")

  3. text.insert("here", "插")

  4. text.insert("here", "入")

例3,如果 Mark 周围的文本被删除了,Mark 仍然还在噢(只是它后边的那货被删除了,所以它六神无主,只能初始化为 "1.0"): 

 
  
  1. text.insert("insert", "I love Python")

  2. text.mark_set("here", "1.2")

  3. text.insert("here", "插")

  4. text.delete("1.0", "end")

  5. text.insert("here", "入")



例4,只有 mark_unset() 方法可以解除 Mark 的封印:

 
  
  1. text.insert("insert", "I love Python")

  2. text.mark_set("here", "1.2")

  3. text.insert("here", "插")

  4. text.mark_unset("here")

  5. text.delete("1.0", "end")

  6. text.insert("here", "入")



看,其实也没有那么难嘛~

好,讲最后一点,我们看到了,默认插入内容到 Mark,是插入到它的左侧(就是说插入一个字符的话,Mark 向后移动了一个字符的位置)。那能不能插入到 Mark 的右侧呢?其实是可以的,通过 mark_gravity() 方法就可以实现。

例5(对比例2):

 
  
  1. text.insert("insert", "I love Python")

  2. text.mark_set("here", "1.2")

  3. text.mark_gravity("here", "left") #默认是 "right"

  4. text.insert("here", "插")

  5. text.insert("here", "入")

由于Text 组件的功能实在太强大,内容较多,剩下的下节课继续讲解。

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