¿Cuál es la forma más eficiente de obtener el total de líneas de visualización de un widget Tkinter Text después de la inserción?

¿Existe una forma más eficiente de obtener el número total de líneas de visualización (no solo las visibles) que quedan en un widget de Text tkinter después de la inserción de texto que con esta función improvisada que tkinter (en Python 3.4.2):

 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 

De todos modos, este código funciona, pero es bastante ineficiente. Lo estoy usando para calcular el tiempo restante para el desplazamiento automático a través del documento restante. La ineficiencia causa problemas al mover el texto insertado con las teclas de flecha (que llama a esta función para mostrar la hora exacta actual). Hace que mover el inserto sea mucho más lento y más lento de actualizar, e incluso puede bloquearlo / congelarlo.

Sé que hay formas mucho más eficientes de obtener el número total de líneas en un widget de texto. Sin embargo, necesito las líneas de visualización, porque la lectura con autoscroll generalmente se realiza con el ajuste de palabras activado.

Mi función de desplazamiento automático baja desde la inserción de un número de líneas elegidas por el usuario cada tantos segundos (el usuario también elige el número de segundos). No se hace a través de las barras de desplazamiento.

Si solo se preocupa por el tiempo para desplazarse por el documento, y si los datos no cambian a medida que avanza (es decir, no se están agregando nuevas líneas), simplemente puede calcular cuántos píxeles ocupa el documento ( solo tiene que hacer esto una vez), y donde se encuentra actualmente en el documento. Eso te dirá cuántos píxeles quedan. A partir de eso, debería poder calcular una aproximación de cuánto tiempo tomará.

Puede obtener el número total de píxeles utilizados en el widget de texto con myTextWidget.count("1.0", "end", "ypixels" . A continuación, puede obtener la coordenada y de la línea actual con myTextWidget.dlineinfo("insert") A partir de esos dos números, puede calcular un porcentaje de lo lejos que está el punto de inserción desde el final del widget.

Bien, encontré una respuesta (y sí, esta es una respuesta intencionalmente; no es parte de mi pregunta).

El siguiente código proporcionará de manera mucho más eficiente el número de líneas de visualización que quedan después de la inserción del texto:

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

Aunque esto es mucho más eficiente, aún no es totalmente eficiente y tendrá problemas con archivos grandes (si está utilizando mucho las teclas de flecha durante el desplazamiento automático). El método count () devuelve una tupla; De ahí, el índice cero. Debido a que esto no siempre contiene un número (como cuando el inserto está al final del documento), es por eso que uso un bloque try / except (aunque puede hacerlo de muchas otras formas; como quiera).

Debido a que esto no es eficiente para archivos grandes, es posible que solo quede las líneas actuales una vez, guárdelas e incremente / disminuya esta variable cuando actualice el estado (otorgado, eso requerirá editar muchas funciones, pero es más eficiente) . Sin embargo, deberá actualizar el total durante las ediciones (afortunadamente, esto es menos común durante el desplazamiento automático).

Debido a que jugar con muchas otras funciones conlleva una gran sobrecarga y aumenta la complejidad de editar el código, sugiero que solo se actualice en los intervalos de desplazamiento automático, en lugar de cuando el usuario mueva el cursor manualmente. Además, para boost la eficiencia, no haga que calcule las líneas que quedan en el método de actualización de la barra de estado, sino que solo lo calcule en una variable guardada a partir del método llamado por el temporizador, y simplemente imprima Variable en la barra de estado.