tkinter文本框同步滚动

  • 引言
  • 尝试
  • 改进
  • 实现
  • 总结

引言

不仅是在CSDN的Markdown编辑器中,在很多编辑器里,编辑文本框和呈现文本框是可以同步滚动的。这样既能体现即时呈现,也能方便编写者找到需要修改的位置。
因此,我希望实现用tkinter实现至少两个文本框的同步滚动。
介于需要绑定事件,为了方便,我在这里仅绑定<MouseWheel>事件,即鼠标滚动。

尝试

在网络上,其实也有一些文章关于tkinter文本框的同步滚动,其中都给出了如下代码:

from tkinter import *def Wheel(event):#鼠标滚轮动作print(str(-1*(event.delta/120)))#windows系统需要除以120text2.yview_scroll(int(-1*(event.delta/120)), "units")text1.yview_scroll(int(-1*(event.delta/120)), "units")
root=Tk()
frame1=Frame(root)
frame1.pack()
text1=scrolledtext.ScrolledText(frame1)
text1.grid(row=0,column=0)
text2=scrolledtext.ScrolledText(frame1)
text2.grid(row=0,column=2)
for ii in range(50):text1.insert(tk.INSERT,str(ii)+'\n')#便于展示效果text2.insert(tk.INSERT,str(ii)+'\n')
text1.bind("<MouseWheel>", Wheel)
text2.bind("<MouseWheel>", Wheel)
root.mainloop()

实现的效果如下:

这段代码确实实现了同步滚动,但是,我们不难发现,这只能实现同时向上或向下滚动,而无法准确地显示文本框对应的位置,两个文本框内容差距甚远。

改进

既然<MouseWheel>返回的event没有用,那么我们干脆不用event作为参数,另辟蹊径。
事实上,最简单的办法就是得到文本框可视范围相对整个文本框内容的位置,同时调整另一个被绑定同步滚动的文本框。举个栗子:

#...
#假设代表位置的参数为y
def Wheel(y,other:list):#other是需要绑定同步滚动的文本框名称列表for i in other:i.yview('moveto',y)#调整纵向可视范围#...
text1=scrolledtext.ScrolledText(frame1)
text1.grid(row=0,column=0)
text2=scrolledtext.ScrolledText(frame1)
text2.grid(row=0,column=2)
#y=??
text1.bind("<MouseWheel>",lambda event: Wheel(y,[text1,text2]))
text2.bind("<MouseWheel>",lambda event: Wheel(y,[text1,text2]))
#...

由此看来,只要获得了“y”,就可以实现同步滚动了。

~~本着能懒就懒的原则,~~先来找找Text组件源码中是否有能够返回目标文本框可视范围的函数。我目前学到初二,英语水平大致能够看懂源码中的注释,但是能够确定的是,文本框组件没有这类函数……

不过别忘了,我们用的是ScrolledText,还有滚动条可用。在Python的tkinter\scrolledtext.py中,我们可以看到文本框的滚动条绑定:

#...
self.vbar = Scrollbar(self.frame)
self.vbar.pack(side=RIGHT, fill=Y)
kw.update({'yscrollcommand': self.vbar.set})
Text.__init__(self, self.frame, **kw)
self.pack(side=LEFT, fill=BOTH, expand=True)
self.vbar['command'] = self.yview
# Copy geometry methods of self.frame without overriding Text
# methods -- hack!
#意思是:复制Frame的外观和属性,但不覆盖文本框(Frame是底层组件,这里省略)
text_meths = vars(Text).keys()
methods = vars(Pack).keys() | vars(Grid).keys() | vars(Place).keys()
methods = methods.difference(text_meths)for m in methods:if m[0] != '_' and m != 'config' and m != 'configure':setattr(self, m, getattr(self.frame, m))
#...

滚动条是 self.vbar,在例子中是 text1.vbar

在滚动条中,使用 get() 函数即可获得滚动条的位置(0.0~1.0)。
现在我们可以继续实现真正的同步滚动了。

实现

总结前面的内容,最终编写以下代码:

#导入、窗口创建、窗口虚幻部分省略
#...
def Wheel(text,other:list):#text是作为可视范围依据的文本框#other是需要绑定同步滚动的文本框名称列表first,end=text.vbar.get()#get会返回滚动条距离顶端和低端相对位置,一般使用距离顶端的相对位置for i in other:i.yview('moveto',first)#调整纵向可视范围#...
text1=scrolledtext.ScrolledText(frame1)
text1.grid(row=0,column=0)
text2=scrolledtext.ScrolledText(frame1)
text2.grid(row=0,column=2)text1.bind("<MouseWheel>",lambda event: Wheel(text1,[text1,text2]))
text2.bind("<MouseWheel>",lambda event: Wheel(text2,[text1,text2]))
#...

改进后效果如下


Tin知识库
这样就可以使编辑框和呈现框处在内容大致对应的可是范围了

总结

其实这是两种截然不同的同步滚定方法,只不过我改进后可以实现显示同一个可视范围。
第一种同步滚动虽然不便用于编辑器,但也有其相应的应用场景,如应用于显示行数基本一致的两段对比材料,方便读者比对文本具体差别。

☀tkinter创新☀

tkinter文本框同步滚动相关推荐

  1. python滚动文本框_调整滚动Tkinter文本框的大小

    我想要一个滚动的Tkinter文本框来填充最大的分配空间.我有点工作...在 由于某些原因,当我拉伸窗口时,文本小部件很好:但是,滚动条在x轴上有大量的填充.在 第二个问题是当我缩小窗口时,屏幕上的滚 ...

  2. tkinter向文本框里加内容_给tkinter文本框添加右键菜单

    给tkinter文本框添加右键菜单 需求:直接右键点击使用tkinter创建的文本框是不会弹出菜单的.我们需要实现右键点击tkinter框架下的Entry对象.Text对象后弹出右键菜单可复制.粘贴和 ...

  3. tkinter文本框小功能(6):锚点

    tkinter文本框小功能(6):锚点 引言 添加标识 添加锚点 python层面 Tin层面 结语 引言 锚点之一概念在文本浏览中很常见,那就是在同一页面的文本内容在,添加一个锚点标识符,指向一个确 ...

  4. python获取文本框里输入的值_如何从Tkinter文本框小工具获取输入?

    要从python 3中的文本框中获取Tkinter输入,我使用的完整学生级程序如下: #Imports all (*) classes, #atributes, and methods of tkin ...

  5. Tkinter:文本框Entry

    文本框Entry 文章目录 文本框Entry 文本框基本概念 options参数 使用show隐藏字符 get()方法 insert()方法 delete()方法 例子:计算 eval()函数介绍 d ...

  6. python tkinter 文本框全选_Python Tkinter Entry(文本框)

    Python学习记录--关于Tkinter Entry(文本框)的选项.方法说明,以及一些示例. 属性(Options) background(bg) Type: color 说明:文本框的背景颜色 ...

  7. html文本框同步,同步组合框HTML文本框与

    +---------+------------+ | class | name | +---------+------------+ | 10021 | John | | 10027 | Alex | ...

  8. Java swing 实现下拉框和文本框同步显示

    想要MyEclipse中的swing中实现下拉框和文本框实现,对下拉框创建MouseEvent.ItemEvent.ActionEvent private void xingbieMouseClick ...

  9. python怎么设置文本框大小_如何在Python中更改Tkinter文本框的宽度和高度?

    所以我一直在用Tkinter在Python上开发一个计算器.不过,我想把按钮隔开,而不是把它们直接放在一起.我不使用root.Frame函数.这是我的代码:from Tkinter import * ...

最新文章

  1. 使用基本的socket函数
  2. python编程零基础-编程零基础应当如何开始学习 Python?
  3. Java设计模式-工厂模式(1)简单工厂模式
  4. ffmpeg 硬件解码rtsp流_树莓派使用硬件加速视频转码
  5. 找某個ColumnName在那些Tables
  6. 真实收货地址大全2016_中国古典诗词大全汇集了诗经、唐诗、宋词、元曲以及纳兰词,12册精美套装。...
  7. python3.6sysos_求大佬,这是什么情况啊
  8. diskfileitemfactory 需要的包_浅析电动汽车电池包低压线束设计及制造
  9. “农业大数据”专题征文通知
  10. 细节打满,IO 操作必须手动关闭?关闭流方法是否有顺序?
  11. 输入问题C++字符数组越界问题的一个案例分析
  12. Hbuilder启动夜神游模拟器失败,解决方案
  13. mysql时间类型英文_英文日期格式及缩写
  14. 函数-6已知输入为一个列表,列表中的元素都为整数,我们定义元素筛选函数为foo,功能是检查获取传入列表对象的所有奇数位索引(注意列表的索引是从0开始的)对应的元素,并将其作为新列表返回给调用者。
  15. 【计算机网络】实验1:双绞线制作
  16. Unity+Kinect 开发脚本介绍
  17. 怎样抠图怎么把背景换成白色?几个步骤教你轻松掌握
  18. Python 安装包环境小问题:WARNING: The repository located at pypi.douban.com is not a trusted or secure host a
  19. PT_二维随机变量:正态分布的可加性/一维随机变量函数与正态分布
  20. html提示用Safari浏览器打开,Safari浏览器无法打开网页怎么办 Safari打不开网站原因及解决方法...

热门文章

  1. 莆田python培训
  2. matplotlib画图之设置横轴坐标上下限的两种方法
  3. 在ubuntu上安装nodebb
  4. moxa uport1150串口驱动下载地址及安装方式
  5. 华为ModelArts自定义镜像(PyTorch镜像)
  6. English语法_形容词/副词3级 - 比较级
  7. Python做游戏很难吗—来看看我做的多有意思~
  8. 相等和严格相等(==和===)
  9. 1030 Travel Plan (30分)(俺是个粗人)
  10. linux怎么创建用户登录,如何创建一个不能登录的Linux用户名