2010-08-23 24 views
6

Tôi gặp sự cố về hiệu suất khi chèn nhiều hàng vào một thanh công cụ GTK (sử dụng PyGTK) - hoặc khi sửa đổi nhiều hàng. Vấn đề là mô hình dường như được sử dụng sau mỗi thay đổi (chèn/sửa đổi). Điều này làm cho GUI bị treo trong nhiều giây. Để mô hình không được phân loại bằng cách bình luận ra model.set_sort_column_id(SOME_ROW_INDEX, gtk.SORT_ASCENDING) sẽ loại bỏ những vấn đề này.GtkTreeXem hình phạt hiệu suất chèn/cập nhật do sắp xếp

Vì vậy, tôi muốn vô hiệu hóa sắp xếp trong khi tôi chèn hoặc sửa đổi mô hình và bật lại sau đó. Rất tiếc, không thể tắt phân loại với model.set_sort_column_id(-1, gtk.SORT_ASCENDING). Sử dụng chức năng đóng băng/tan băng không hoạt động hoặc:

treeview.freeze_child_notify() 

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

Vì vậy, làm thế nào tôi có thể vô hiệu hóa các phân loại? Hoặc là có một phương pháp tốt hơn cho chèn số lượng lớn/sửa đổi?


Giải pháp

Nhờ các thông tin và liên kết bobince cung cấp trong câu trả lời của mình, tôi đã kiểm tra ra một số lựa chọn thay thế:

1) Dummy sắp xếp

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

Điều này mang thời gian xuống từ khoảng 11 giây đến 2 giây. Wow! Nhưng có thể tốt hơn, đây chỉ là 1000 hàng.

2) Loại bỏ mô hình khi cập nhật

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

Không khác biệt đáng chú ý, 11 giây.

3) Dummy phân loại và lừa máy phát điện mát mẻ từ 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) 

Kết quả: Cùng khoảng 2 giây như trong dung dịch 1), nhưng GUI phản ứng trong thời gian này. Tôi thích phương pháp này. Modulo 200 có thể được tinh chỉnh để làm cho GUI ít nhiều phản ứng nếu cần thiết.

Thậm chí có thể phân lớp gtk.TreeStore để nhận kết quả tốt hơn? Chưa thử, nhưng tùy chọn 3) là đủ tốt cho bây giờ.

Trả lời

2

Nghe có vẻ như bạn đang ở gần đó. Xem FAQ để biết thêm ghi chú. Cụ thể, bạn cũng nên đặt default_sort_order (bây giờ bạn có thể sử dụng None cũng như giả so sánh lambda trong ví dụ đó để có hiệu suất tốt hơn) để đảm bảo không có sắp xếp và xóa mô hình khỏi treeview trong suốt thời gian hoạt động .

Nếu có nhiều thay đổi, bạn có thể nên tạo và thiết lập mô hình hoàn chỉnh mới.

+0

Cảm ơn, điều đó thực sự hữu ích :) Xem câu hỏi của tôi về một số giải pháp mà tôi đã thử nghiệm dựa trên thông tin bạn đã cung cấp. – AndiDog

Các vấn đề liên quan