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ờ.
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