python tkinter - 想要在ScrolledText小部件中单击滚动条时调用函数

时间:2013-09-17 00:29:13

标签: python tkinter scrollbar

[编辑指出:] 我想挂钩ScrolledText小部件,以便当用户点击滚动条中的任何位置(或者甚至用鼠标滚轮滚动它,希望)我可以让它调用回调函数,我可以 [添加:“设置一个标志,然后返回让ScrolledText小部件做它的事情。”] [删除:“在滚动操作发生之前先执行某些操作(例如关闭自动滚动)。”]

这可能吗?

由于

2 个答案:

答案 0 :(得分:1)

无法到达ScrolledText内部以获取Scrollbar和Text并挂钩它们的绑定。

而且,当你可以这样做时,那时为什么要使用ScrolledText?重点是,无需你理解它就可以自动滚动绑定。如果您不想这样,请直接使用ScrollbarTextTkinter Scrollbar Patterns解释了如何详细地做到这一点,但实际上,如果你不想做任何不寻常的事情,它只是将每个消息与另一个方法连接起来。

例如:

from Tkinter import *

def yscroll(*args):
    print('yscroll: {}'.format(args))
    scrollbar.set(*args)

def yview(*args):
    print('view: {}'.format(args))
    textbox.yview(*args)

root = Tk()    
scrollbar = Scrollbar(root)
scrollbar.pack(side=RIGHT, fill=Y)    
textbox = Text(root, yscrollcommand=yscroll)
for i in range(1000):
    textbox.insert(END, '{}\n'.format(i))
textbox.pack(side=LEFT, fill=BOTH)
scrollbar.config(command=yview)
mainloop()

如果你不能从(有时令人困惑和不完整)的文档中弄出细节,那就玩吧。基本上,每当移动滚动条时都会调用yview,并且每当滚动视图时都会调用yscrollyscroll的论点是显而易见的;那些yview不那么重要,但文档确实很好地解释了它们。

请注意,当您正常设置时,拖动滚动条或滑动触控板或在滚动条上滚动鼠标滚轮会发送yview,这会使我们的代码调用textbox.yview,然后发送yscroll,而会导致新yview(否则会出现无限循环)。所以,你看到两个方法都被调用了。另一方面,滑动触控板或在文本上滚动鼠标滚轮,或使用键盘从底部移开,会发送yscroll,这也不会导致yview,所以在这种情况下你只看到两种方法中的一种。

因此,例如,如果您将yview更改为不调用textbox.yview,则可以随意拖动滚动条,但文本视图不会移动。如果您将yscroll更改为不调用scrollbar.set,则可以随意滑动文本,但滚动条不会移动。

如果你想要一个水平滚动条,除了用x代替y之外,一切都是一样的。但是ScrolledText不进行水平滚动,所以我假设你不想要它。


如果您确实想深入了解ScrolledText,可以查看the source的版本,如果您了解上述示例,这非常简单。事实上,它基本上只是围绕上述示例的OO包装器。

至少在2.7和3.3中,ScrolledText本身就是Text,其self.vbarScrollbar。它在其超类初始化中设置yscrollcommand=self.vbar.set,并在构造self.vbar['command'] = self.yview之后设置vbar。就是这样。

因此,只需删除显式scrollbar创建,并将其作为textbox.vbar访问,并且上述相同的挂钩代码的工作方式相同:

from Tkinter import *
from ScrolledText import *

def yscroll(*args):
    print('yscroll: {}'.format(args))
    textbox.vbar.set(*args)

def yview(*args):
    print('yview: {}'.format(args))
    textbox.yview(*args)

root = Tk()    
textbox = ScrolledText(root)
for i in range(1000):
    textbox.insert(END, '{}\n'.format(i))
textbox.pack(side=LEFT, fill=BOTH)
textbox['yscrollcommand'] = yscroll
textbox.vbar.config(command=yview)
mainloop()

请注意,textbox是正常的Text,而textbox.vbar是附加的Scrollbar这一事实在任何地方都没有记录,所以它可以理论上改变了一天。

答案 1 :(得分:1)

你想做某事喜欢关闭自动滚动,还是实际你想做什么?

如果要打开或关闭自动滚动,只需在插入文本前检查文本的位置。如果它在最后,添加文本并自动滚动。如果它不在最后,添加文本但不滚动。即使它们通过某些其他机制(例如使用向上翻页/向下翻页键)滚动,这也会起作用。

您可以检查几种不同的方式。我认为我一直这样做的方式(现在不在我的桌面上进行检查,已经过了几年......)就是在最后一个角色上调用dlineinfo。如果最后一个字符不可见,则此命令将返回None。您还可以使用yview命令查看可查看范围是否扩展到底部。对于第一个和最后一个可见线,它返回两个在0和1之间的分数。

虽然用户无法通过单击按钮来打开或关闭自动滚动,但这可以说是更好的,因为当它们向后滚动以查看某些内容时它“会发生”。