Je rencontre des problèmes de performance lorsque j'insère plusieurs lignes dans une arborescence GTK (en utilisant PyGTK) - ou lorsque je modifie plusieurs lignes. Le problème est que le modèle semble avoir recours après chaque changement (insertion/modification). Cela provoque l'arrêt de l'interface graphique pour plusieurs secondes. Laisser le modèle non trié en commentant model.set_sort_column_id(SOME_ROW_INDEX, gtk.SORT_ASCENDING)
élimine ces problèmes. Par conséquent, je voudrais désactiver le tri pendant que j'insère ou modifie le modèle, et le réactiver par la suite. Malheureusement, le tri ne peut pas être désactivé avec model.set_sort_column_id(-1, gtk.SORT_ASCENDING)
. En utilisant les fonctions de gel/dégel ne fonctionne pas non plus:GtkTreeView insertion/mise à jour pénalité de performance à cause du tri
treeview.freeze_child_notify()
try:
for row in model:
# ... change something in row ...
finally:
treeview.thaw_child_notify()
Alors, comment puis-je désactiver le tri? Ou existe-t-il une meilleure méthode pour les insertions/modifications en masse?
Solution
Merci à l'information et des liens bobince fournis dans sa réponse, j'ai vérifié quelques-unes des alternatives:
1) Dummy tri
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()
Cela a ramené le temps d'environ 11 secondes à 2 secondes. Hou la la! Mais pourrait être mieux, c'était seulement pour 1000 lignes.
2) Suppression de modèle en mettant à jour
tv.set_model(None)
# change rows
tv.set_model(model)
Aucune différence notable, 11 secondes.
3) Dummy tri et le tour du générateur fraîche 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)
Résultat: Les mêmes environ 2 secondes, comme dans la solution 1), mais l'interface graphique utilisateur réagit pendant ce temps. Je préfère cette méthode. Le modulo 200 peut être modifié pour rendre l'interface plus ou moins réactive si nécessaire.
Peut-être que même il est possible de sous-classer gtk.TreeStore
pour obtenir de meilleurs résultats? Je n'ai pas encore essayé, mais l'option 3) est suffisante pour le moment.
Merci, ce fut vraiment utile :) Voir ma question pour quelques solutions que j'ai testé en fonction de l'information que vous avez fournie. – AndiDog