[编辑说明:]我想挂接到 ScrolledText 小部件,这样当用户单击滚动条中的任何位置(或者甚至希望用鼠标滚轮滚动它)时,我可以让它调用一个回调函数,我可以在其中 [添加:“设置一个标志,然后返回让 ScrolledText 小部件执行它的操作。”] [删除:“在滚动操作发生之前先做某事(例如关闭自动滚动)。”]
这可能吗?
谢谢
您是否想做诸如关闭自动滚动之类的事情,或者这实际上是您想要做的事情?
如果要打开或关闭自动滚动,只需在插入文本之前检查文本的位置。如果它在末尾,请添加文本并自动滚动。如果它不在末尾,请添加文本但不要滚动。即使他们通过其他机制滚动,例如使用向上/向下翻页键,这也将起作用。
您可以检查几种不同的方法。我认为我一直这样做的方式(不是现在在我的桌面上检查,而且已经有几年了......)是调用dlineinfo
最后一个角色。如果最后一个字符不可见,则此命令将返回None
. 您还可以使用该yview
命令查看可视范围是否延伸到底部。它为第一条和最后一条可见行返回两个数字,它们是零和一之间的分数。
虽然用户无法通过单击按钮来打开或关闭自动滚动,但这可以说更好,因为当他们向后滚动查看某些内容时它会“发生”。
并非没有进入 ScrolledText 内部以获取 Scrollbar 和 Text 并挂钩它们的绑定。
而且,虽然你可以做到这一点,但为什么还要使用ScrolledText
? 重点是它会自动执行滚动绑定,而无需您理解它们。如果你不想这样,直接使用 aScrollbar
和 a Text
。Tkinter 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
,您可以随意滑动文本,但滚动条不会移动。
如果你也想要一个水平滚动条,除了x
用y
. 但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
)在任何地方都没有记录,因此理论上它可能有一天会改变。