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

上节课我们介绍了Text组件的Indexs 索引和 Marks 标记,它们主要是用于定位,Marks 可以看做是特殊的 Indexs,但是它们又不是完全相同的,比如在默认情况下,你在Marks指定的位置中插入数据,Marks 的位置会自动发生改变, 因为Marks 认它后面的“那个家伙”,当 Marks 前面的数据被删除时,Marks 并不会被删除,它的位置只是相应的向前移动了,只有 mark_unset() 方法 才能够删除Marks,这节课我们接着来介绍 Tags 的用法。

Tags(标签)通常用于改变 Text 组件中内容的样式和功能。你可以修改文本的字体、尺寸和颜色。另外,Tags 还允许你将文本、嵌入的组件和图片与键盘和鼠标等事件相关联。除了 user-defined tags(用户自定义的 Tags),还有一个预定义的特殊 Tag:SEL。

SEL(或 "sel")用于表示对应的选中内容(如果有的话)。

你可以自定义任意数量的 Tags,Tags 的名字是由普通字符串组成,可以是除了空白字符外的任何字符。另外,任何文本内容都支持多个 Tags 描述,任何 Tag 也可以用于描述多个不同的文本内容。

我们来举个例子:

 
  1. import tkinter as tk

  2. root = tk.Tk()

  3. text = tk.Text(root, width=40, height=5,)

  4. text.pack()

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

  6. text.tag_add("tag1", "1.7", "1.13", "1.15")

  7. text.tag_config("tag1", background = "yellow", foreground = "red")

  8. root.mainloop()

还有一点需要注意的是:如果你对同一个范围内的文本加上多个 Tags,并且设置相同的选项,那么新创建的 Tag 样式会覆盖比较旧的 Tag:

 
  1. import tkinter as tk

  2. root = tk.Tk()

  3. text = tk.Text(root, width=40, height=5)

  4. text.pack()

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

  6. text.tag_add("tag1", "1.7", "1.13", "1.15")

  7. text.tag_add("tag2", "1.7", "1.13", "1.15")

  8. text.tag_config("tag2", foreground = "green")

  9. text.tag_config("tag1", background = "yellow", foreground = "red")

  10. root.mainloop()

那么新创建的 Tag2 会覆盖比较旧的 Tag1 的相同选项, 注意,与下边的调用顺序没有关系

你或许想控制 Tags 间的优先级,这可以实现吗?完全没有问题!你可以使用 tag_raise() 和 tag_lower() 方法来提高和降低某个 Tag 的优先级。

 
  1. import tkinter as tk

  2. root = tk.Tk()

  3. text = tk.Text(root, width=40, height=5)

  4. text.pack()

  5. text.tag_config("tag1", background="yellow", foreground="red")

  6. text.tag_config("tag2", foreground="green")

  7. text.tag_lower("tag2")

  8. text.insert("insert", "I love Python!", ("tag2", "tag1"))

  9. root.mainloop()

另外 Tags 还支持事件绑定,使用的是 tag_bind() 的方法。

下边例子中我们将文本("Python.com")与鼠标事件进行绑定,当鼠标进入该文本段的时候,鼠标样式切换为 "arrow" 形态,离开文本段的时候切换回 "xterm" 形态。当触发鼠标“左键点击操作”事件的时候,使用默认浏览器打开Python的首页(Welcome to Python.org):

 
  1. import tkinter as tk

  2. import webbrowser

  3. root = tk.Tk()

  4. text = tk.Text(root, width=40, height=5)

  5. text.pack()

  6. text.insert("insert", "I love Python.com!")

  7. text.tag_add("link", "1.7", "1.17")

  8. text.tag_config("link", foreground = "blue", underline = True)

  9. def show_arrow_cursor(event):

  10. text.config(cursor = "arrow")

  11. def show_xterm_cursor(event):

  12. text.config(cursor = "xterm")

  13. def click(event):

  14. webbrowser.open("https://www.python.org/")

  15. text.tag_bind("link", "<Enter>", show_arrow_cursor)

  16. text.tag_bind("link", "<Leave>", show_xterm_cursor)

  17. text.tag_bind("link", "<Button-1>", click)

  18. root.mainloop()

接下来给大家介绍几个 Tags 使用上的技巧:

(一)判断内容是否发生变化

通过校检 Text 组件中文本的 MD5 摘要来判断内容是否发生改变

 
  1. import tkinter as tk

  2. import hashlib

  3. root = tk.Tk()

  4. text = tk.Text(root, width=40, height=5)

  5. text.pack()

  6. text.insert("insert", "I love Python.com!")

  7. contents = text.get("1.0", "end")

  8. def getSig(contents):

  9. m = hashlib.md5(contents.encode())

  10. return m.digest()

  11. sig = getSig(contents)

  12. def check():

  13. contents = text.get("1.0", "end")

  14. if sig != getSig(contents):

  15. print("警报:内容发生改变!")

  16. else:

  17. print("风平浪静")

  18. tk.Button(root, text = "检查", command = check).pack()

  19. root.mainloop()

(二)查找操作

使用 search() 方法可以搜索 Text 组件中的内容。但是传统的 search() 方法只查找到一个,就返回,我们可以加入一个循环,查找所有的。

 
  1. import tkinter as tk

  2. import hashlib

  3. root = tk.Tk()

  4. text = tk.Text(root, width=40, height=5)

  5. text.pack()

  6. text.insert("insert", "I love Python.com!")

  7. def getIndex(text, index):

  8. return tuple(map(int, str.split(text.index(index), ".")))

  9. start = "1.0"

  10. while True:

  11. pos = text.search("o", start, stopindex = "end")

  12. if not pos:

  13. break

  14. print("找到啦,位置是:", getIndex(text, pos))

  15. start = pos + "+1c"

  16. root.mainloop()

(三)恢复、撤销操作

Text 组件还支持“恢复”和“撤销”操作,这使得 Text 组件显得相当高大上。

通过设置 undo 选项为 True 可以开启 Text 组件的“撤销”功能。然后用 edit_undo() 方法实现“撤销”操作,用 edit_redo() 方法实现“恢复”操作。

 
  1. import tkinter as tk

  2. import hashlib

  3. root = tk.Tk()

  4. text = tk.Text(root, width=40, height=5, undo = True)

  5. text.pack()

  6. text.insert("insert", "I love Python.com!")

  7. def show():

  8. text.edit_undo()

  9. tk.Button(root, text = "撤销", command = show).pack()

  10. root.mainloop()

 Text 组件内部有一个栈专门用于记录内容的每次变动,所以每次“撤销”操作就是一次弹栈操作,“恢复”就是再次压栈。

默认情况下,每一次完整的操作将会放入栈中。但怎么样算是一次完整的操作呢?Tkinter 觉得每次焦点切换、用户按下 Enter 键、删除\插入操作的转换等之前的操作算是一次完整的操作。也就是说你连续输入“I love Python” 的话,一次的“撤销”操作就会将所有的内容删除。

那我们能不能自定义呢?比如我希望插入一个字符就算一次完整的操作,然后每次点击“撤销”就去掉一个字符。

当然可以!做法就是先将 autoseparators 选项设置为 False(因为这个选项是让 Tkinter 在认为一次完整的操作结束后自动插入“分隔符”),然后绑定键盘事件,每次有输入就用 edit_separator() 方法人为地插入一个“分隔符”:

 
  1. import tkinter as tk

  2. import hashlib

  3. root = tk.Tk()

  4. text = tk.Text(root, width=40, height=5, undo = True, autoseparators = False)

  5. text.pack()

  6. text.insert("insert", "I love Python.com!")

  7. def callback(event):

  8. text.edit_separator() #人为插入分隔符

  9. text.bind('<Key>', callback)

  10. def show():

  11. text.edit_undo()

  12. tk.Button(root, text = "撤销", command = show).pack()

  13. root.mainloop()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/11822.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

yaml语法详解

#kv #对空格的严格要求十分高 #注入到我们的配置类中 #普通的keyvalue name: qinjiang#对象 student:name: qingjiangage: 3#行内写法 student1: {name: qinjiang,age: 3}#数组 pets:- cat- dog- pigpet: [cat,dog,pig]yaml可以给实体类赋值 person:name: kuangshenage: 19happ…

Android onTouchEvent方法不触发ACTION_UP的解决方法

Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN://触摸、按下setImageResource(R.mipmap.ic_music);break;case MotionEvent.ACTION_UP://抬起setImageResource(R.mipmap.ic_launcher);break;}return sup…

ERROR 1064 - You have an error in your SQL syntax;

ERROR 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near (/, 少个逗号吧&#xff0c;以前开始写SQL&#xff0c;特别是修改SQL的时候容易出现这样错误。 而且自己也知道在附近…

前端异常错误处理(包括但不限于react,vue)

错误异常发生 页面js报错请求报错页面资源加载报错promise异常iframe加载异常页面奔溃&卡顿异常 处理异常的方法 1、react 自带的errorBoundaries 2、 react 自定义Hooks 3、 vue errorHandler 4、try catch 对特定的代码进行捕获 5、window.addEventListerner …

【深度学习】日常笔记15

训练集和测试集并不来⾃同⼀个分布。这就是所谓的分布偏移。 真实⻛险是从真实分布中抽取的所有数据的总体损失的预期&#xff0c;然⽽&#xff0c;这个数据总体通常是⽆法获得的。计算真实风险公式如下&#xff1a; 为概率密度函数 经验⻛险是训练数据的平均损失&#xff0c;⽤…

【MySQL主从复制】

目录 一、MySQL Replication 1.概述 2.优点 二、MySQL复制类型 1.异步复制&#xff08;Asynchronous repication&#xff09; 2.全同步复制&#xff08;Fully synchronous replication&#xff09; 3.半同步复制&#xff08;Semisynchronous replication&#xff09; 三…

【Rust 基础篇】Rust FFI:连接Rust与其他编程语言的桥梁

导言 Rust是一种以安全性和高效性著称的系统级编程语言&#xff0c;具有出色的性能和内存安全特性。然而&#xff0c;在现实世界中&#xff0c;我们很少有项目是完全用一种编程语言编写的。通常&#xff0c;我们需要在项目中使用多种编程语言&#xff0c;特别是在与现有代码库…

ava版知识付费平台免费搭建 Spring Cloud+Spring Boot+Mybatis+uniapp+前后端分离实现知识付费平台

提供私有化部署&#xff0c;免费售后&#xff0c;专业技术指导&#xff0c;支持PC、APP、H5、小程序多终端同步&#xff0c;支持二次开发定制&#xff0c;源码交付。 Java版知识付费-轻松拥有知识付费平台 多种直播形式&#xff0c;全面满足直播场景需求 公开课、小班课、独…

Rust ESP32C3开发

Rust ESP32C3开发 系统开发逐步使用Rust语言&#xff0c;在嵌入式领域Rust也逐步完善&#xff0c;本着学习Rust和ESP32的目的&#xff0c;搭建了ESP32C3的环境&#xff0c;过程中遇到了不少问题&#xff0c;予以记录。 ESP-IDF开发ESP32 这一部分可跳过&#xff0c;是使用C开…

tensorflow错误及解决办法

tf.graph 节点没有数据 tensorflow.python.framework.errors_impl.InvalidArgumentError: Retval[2] does not have value.通过TensorFlow Retval[0] does not have value启发&#xff0c;怀疑是通过tf.cond构建网络图的时候&#xff0c;一次只走一个分支&#xff0c;导致另一…

docker更新jenkins

下载文件 1、jenkins提示下载 2、官网下载jenkins官网 文件放服务器内 通过工具把jenkins.war放进服务器例如tmp 文件复制到docker的jenkins容器 docker cp 路径文件 容器id:/{后面不接内容为根路径} docker cp /tmp/jenkins.war 53dc1c71058a:/进入容器内 docker exec …

golang实现多态

Go 通过接口来实现多态。在 Go 语言中&#xff0c;我们是隐式地实现接口。一个类型如果定义了接口所声明的全部方法&#xff0c;那它就实现了该接口。现在我们来看看&#xff0c;利用接口&#xff0c;Go 是如何实现多态的。 package mainimport "fmt"type Income in…

实训笔记7.28

实训笔记7.28 7.28笔记一、Hive的基本使用1.1 Hive的命令行客户端的使用1.2 Hive的JDBC客户端的使用1.2.1 使用前提1.2.2 启动hiveserver21.2.3 使用方式 1.3 Hive的客户端中也支持操作HDFS和Linux本地文件 二、Hive中DDL语法2.1 数据库的管理2.1.1 创建语法2.1.2 修改语法2.1.…

日期清洗的sql函数

sql语言是postgressql。 函数只处理了 中国格式 &#xff1a; xxxx年-xx月-xx日 美国格式&#xff1a; mm/dd/yyyy&#xff0c; September 04,1991&#xff0c; September 1991&#xff0c; sept 04&#xff0c; 1991 uunix格式&#xff1a; yyyy/mm/dd&#xff0c; yyyy/mm&am…

python测试开发面试常考题:装饰器

目录 简介 应用 第一类对象 装饰器 描述器descriptor 资料获取方法 简介 Python 装饰器是一个可调用的(函数、方法或类)&#xff0c;它获得一个函数对象 func_in 作为输入&#xff0c;并返回另一函数对象 func_out。它用于扩展函数、方法或类的行为。 装饰器模式通常用…

【学习笔记】[ZJOI2019] 开关

之前没认真学 F W T FWT FWT可惜了&#x1f605; 首先要做过这道题 [AGC034F] RNG and XOR 。 考虑 I F W T IFWT IFWT算法的本质&#x1f914; 之前我们注意到将 k k k的顺序调换并不会影响结果&#xff0c;也就是说只要做一遍 F W T FWT FWT&#xff0c;然后再除以 2 n 2^…

【数据结构】实验十一:图

实验十一 图 一、实验目的与要求 1&#xff09;掌握图的存储表示与操作实现。 2&#xff09;掌握图的连通性及其应用。 二、 实验内容 1.用邻接表存储一个图形结构&#xff0c;并计算每个顶点的度。 2. 采用深度和广度优先搜索算法&#xff0c;遍历上述这张图&#xff0c;…

vue 实现拖拽效果

实现方式&#xff1a;使用自定义指令可以实现多个面板拖拽互不影响 1.自定义指令 js directives: {// 拖拽drag(el) {el.onmousedown function (e) {let x e.pageX - el.offsetLeftlet y e.pageY - el.offsetTopdocument.onmousemove function (e) {el.style.left e.pag…

placeholder样式自定义(uniapp 微信小程序、h5)

一、使用uniapp开发 ①第一种方式&#xff1a;&#xff08;写在行内&#xff09; <input type"text" placeholder"姓名" placeholder-style"font-size:28rpx;color:#999999;" />②第二种方式&#xff1a; &#xff08;给input加上placeho…

《向量数据库指南》:向量数据库Pinecone如何集成数据湖

目录 为什么选择Databricks? 为什么选择Pinecone? 设置Spark集群 环境设置 将数据集加载到分区中 创建将文本转换为嵌入的函数 将UDF应用于数据 更新嵌入 摘要 使用Databricks和Pinecone在规模上创建和索引向量嵌入 建立在Apache Spark之上的Databricks是一个强大的…