插入后获取 Tkinter 文本小部件的总显示行的最有效方法是什么?



有没有比我(在Python 3.4.2中)想出的这个临时函数更有效的方法来获取文本插入后tkinter Text小部件中剩余的显示行总数(而不仅仅是可见行):

def get_display_lines():
    #Gets the total number of display lines after the text insert in the current tab (not just those on-screen, though).
    myTextWidget.mark_set("dlines", INSERT)
    count=0
    while 1:
        if myTextWidget.compare("dlines", ">=", "end-1c linestart"):
            break
        else:
            myTextWidget.mark_set("dlines", "dlines + 1 display line")
            count+=1
    return count

不管怎样,这段代码是有效的,但效率相当低。我用它来计算剩余文档中自动滚动的剩余时间。使用箭头键(调用此函数以显示当前准确时间)移动文本插入时,效率低下会导致问题。这会使插入的移动速度减慢,更新速度减慢,甚至可能崩溃/冻结它

我知道有更有效的方法来获得文本小部件中的行总数。然而,我需要显示行,因为使用自动滚动阅读通常是使用换行符完成的。

我的自动滚动功能从每隔几秒插入用户选择的行数开始(秒数也由用户选择)。它不是通过滚动条完成的。

如果你只关心滚动文档的时间,并且数据在滚动时没有改变(即:没有添加新行),你可以简单地计算文档占用的像素数(你只需要这样做一次),以及你当前在文档中的位置。这会告诉你还剩多少像素。由此,您应该能够计算出所需时间的近似值。

您可以使用myTextWidget.count("1.0", "end", "ypixels"获取文本小部件中使用的像素总数。然后,您可以使用myTextWidget.dlineinfo("insert")获得当前直线的y坐标。根据这两个数字,您可以计算插入点距离小部件末端的百分比。

好吧,我找到了答案(是的,这是一个有目的的答案;这不是我问题的一部分)。

以下代码将更有效地提供文本插入后剩余的显示行数:

def get_display_lines(start="insert", end="end-1c")
    try:
        count=myTextWidget.count(start, end, "displaylines")[0]
    except TypeError:
        count=0
    return count

尽管这要高效得多,但它仍然不是完全高效的,并且在处理大文件时会遇到问题(如果您在自动滚动过程中经常使用箭头键)。count()方法返回一个元组;因此零指数。因为它并不总是包含一个数字(就像插入在文档末尾时一样),这就是为什么我使用try/except块的原因(尽管你可以用很多其他方式来做这件事;不管你喜欢什么)。

因为这对大文件来说效率不高,所以您可能只保留一次当前行,保存它们,并在更新状态时递增/递减此变量(当然,这需要编辑一堆函数,但效率更高)。不过,您需要在编辑期间更新总数(幸运的是,在自动滚动时这种情况不太常见)。

由于处理许多其他函数会带来大量开销,并增加编辑代码的复杂性,我建议只在自动滚动间隔更新代码,而不是在用户手动移动光标时更新。此外,为了提高效率,不要让它计算statusbar更新方法中剩下的行(更不用说剩下的时间了),而是只在计时器调用的方法中的保存变量中计算,然后在statusbar中打印变量。

最新更新