1

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

这可能吗?

谢谢

4

2 回答 2

2

您是否想做诸如关闭自动滚动之类的事情,或者这实际上是您想要做的事情?

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

您可以检查几种不同的方法。我认为我一直这样做的方式(不是现在在我的桌面上检查,而且已经有几年了......)是调用dlineinfo最后一个角色。如果最后一个字符不可见,则此命令将返回None. 您还可以使用该yview命令查看可视范围是否延伸到底部。它为第一条和最后一条可见行返回两个数字,它们是零和一之间的分数。

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

于 2013-09-17T02:30:47.333 回答
2

并非没有进入 ScrolledText 内部以获取 Scrollbar 和 Text 并挂钩它们的绑定。

而且,虽然你可以做到这一点,但为什么还要使用ScrolledText? 重点是它会自动执行滚动绑定,而无需您理解它们。如果你不想这样,直接使用 aScrollbar和 a TextTkinter 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只要滚动条移动yscroll就会调用,并且只要滚动视图就会调用。的论点yscroll是显而易见的;那些yview不那么重要,但文档确实很好地解释了它们。

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

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

如果你也想要一个水平滚动条,除了xy. 但ScrolledText不做水平滚动,所以我假设你不想要它。


如果你真的想深入ScrolledText研究,你可以查看你的版本的源代码,如果你理解了上面的例子,这很简单。实际上,它基本上只是上面示例的 OO 包装器。

至少在 2.7 和 3.3 中, theScrolledText本身就是Text, 它self.vbar就是Scrollbar. 它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)在任何地方都没有记录,因此理论上它可能有一天会改变。

于 2013-09-17T00:56:20.223 回答