Tengo problemas de rendimiento al insertar muchas filas en una vista de árbol GTK (usando PyGTK) o al modificar muchas filas. El problema es que el modelo parece ser recurrido después de cada cambio (inserción/modificación). Esto hace que la GUI se cuelgue por varios segundos. Dejar el modelo sin ordenar al comentar model.set_sort_column_id(SOME_ROW_INDEX, gtk.SORT_ASCENDING)
elimina estos problemas.GtkTreeView penalización de rendimiento de inserción/actualización debido a la clasificación
Por lo tanto, me gustaría desactivar la clasificación mientras estoy insertando o modificando el modelo, y volver a habilitarlo después. Desafortunadamente, la clasificación no se puede desactivar con model.set_sort_column_id(-1, gtk.SORT_ASCENDING)
. Usando las funciones de congelación/descongelación no funciona bien:
treeview.freeze_child_notify()
try:
for row in model:
# ... change something in row ...
finally:
treeview.thaw_child_notify()
Entonces, ¿cómo puedo desactivar la clasificación? ¿O hay un método mejor para inserciones/modificaciones a granel?
solución
Gracias a la información y enlaces bobince proporcionado en su respuesta, he comprobado algunas de las alternativas:
1) Maniquí de clasificación
tv.freeze_child_notify()
sortSettings = model.get_sort_column_id()
model.set_default_sort_func(lambda *unused: 0) # <-- can also use None but that is slower!
# model.set_default_sort_func(lambda *unused: 1) <-- slow
# model.set_default_sort_func(lambda *unused: -1) <-- crash (access violation in gtk_tree_store_move_after?!)
model.set_sort_column_id(-1, gtk.SORT_ASCENDING)
# change rows
model.set_sort_column_id(*sortSettings)
tv.thaw_child_notify()
Esto redujo el tiempo de aproximadamente 11 segundos a 2 segundos. ¡Guauu! Pero podría ser mejor, esto fue solo para 1000 filas.
2) Extracción de modelo al actualizar
tv.set_model(None)
# change rows
tv.set_model(model)
No se diferencia notable, 11 segundos.
3) Maniquí clasificación y el fresco truco generador de la PyGTK FAQ
def gen():
tv.freeze_child_notify()
sortSettings = model.get_sort_column_id()
model.set_default_sort_func(lambda *unused: 0)
model.set_sort_column_id(-1, gtk.SORT_ASCENDING)
i = 0
for row in rowsToChange:
i += 1
# change something
if i % 200 == 0:
# freeze/thaw not really necessary here as sorting is wrong because of the
# default sort function
yield True
model.set_sort_column_id(*sortSettings)
tv.thaw_child_notify()
yield False
g = gen()
if g.next(): # run once now, remaining iterations when idle
gobject.idle_add(g.next)
El resultado: Los mismos estimado de 2 segundos como en solución 1), pero la GUI reacciona durante este tiempo. Yo prefiero este método El módulo 200 se puede modificar para hacer que la GUI sea más o menos reactiva si es necesario.
Tal vez es incluso posible la subclase gtk.TreeStore
para obtener mejores resultados? Todavía no lo he intentado, pero la opción 3) es lo suficientemente buena por ahora.
Gracias, fue realmente útil :) Consulte mi pregunta para conocer algunas soluciones que he probado en función de la información que ha proporcionado. – AndiDog