2010-08-23 12 views
6

Mam problemy z wydajnością podczas wstawiania wielu wierszy do widoku drzewa GTK (przy użyciu PyGTK) - lub podczas modyfikowania wielu wierszy. Problem polega na tym, że model wydaje się uciekać po każdej zmianie (wstawienie/modyfikacja). To powoduje, że GUI zawiesza się na kilka sekund. Pozostawienie modelu nieposortowanego przez wykomentowanie model.set_sort_column_id(SOME_ROW_INDEX, gtk.SORT_ASCENDING) eliminuje te problemy.GtkTreeView wstawianie/aktualizowanie kary wydajności z powodu sortowania

Dlatego chciałbym wyłączyć sortowanie podczas wstawiania lub modyfikowania modelu, a następnie włączyć je później. Niestety, sortowanie nie może być wyłączone z model.set_sort_column_id(-1, gtk.SORT_ASCENDING). Korzystanie z funkcji zamrażania/rozmrażania nie działa albo:

treeview.freeze_child_notify() 

try: 
    for row in model: 
     # ... change something in row ... 
finally: 
    treeview.thaw_child_notify() 

Tak, jak mogę wyłączyć sortowanie? Czy istnieje lepsza metoda wprowadzania/modyfikacji luzem?


Rozwiązanie

Dzięki informacjom i linki bobince przewidziane w swojej odpowiedzi, sprawdziłem niektóre z alternatyw:

1) Dummy sortowania

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() 

Spowodowało to spadek czasu z około 11 sekund do 2 sekund. Łał! Ale może być lepiej, to było tylko na 1000 wierszy.

2) usuwanie modelu podczas aktualizacji

tv.set_model(None) 
# change rows 
tv.set_model(model) 

Brak zauważalnej różnicy, 11 sekund.

3) manekin sortowania chłodnej i generator trick w 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) 

Wynik: same oszacowane 2 sekund, w roztworze 1), ale GUI reaguje w tym czasie. Wolę tę metodę. Modulo 200 można zmodyfikować, aby interfejs GUI był bardziej lub mniej reaktywny, jeśli zajdzie taka potrzeba.

Może nawet podklasę gtk.TreeStore można uzyskać, aby uzyskać lepsze wyniki? Jeszcze tego nie próbowałem, ale opcja 3) jest na razie wystarczająco dobra.

Odpowiedz

2

Brzmi, jakbyś był prawie na miejscu. Więcej informacji na ten temat można znaleźć w dokumencie FAQ. W szczególności powinieneś również ustawić default_sort_order (możesz teraz użyć None, a także fikcyjnego porównania lambda w tym przykładzie, dla lepszej wydajności), aby upewnić się, że nie ma sortowania, i usunąć model z widoku drzewa na czas operacji .

Jeśli jest dużo zmian, może lepiej będzie stworzyć i ustawić kompletny nowy model.

+0

Dzięki, to było naprawdę pomocne :) Zobacz moje pytanie dotyczące niektórych rozwiązań, które przetestowałem na podstawie podanych informacji. – AndiDog

Powiązane problemy