Tôi sẽ trích dẫn PyGTK FAQ:
Bạn đã tạo một thanh tiến trình bên trong một cửa sổ, sau đó bạn bắt đầu chạy một vòng lặp mà không một số công việc:
while work_left:
...do something...
progressbar.set_fraction(...)
Bạn sẽ thấy cửa sổ không hiển thị hoặc thanh tiến trình vẫn bị đóng băng cho đến khi kết thúc bài tập. Giải thích rất đơn giản: gtk là sự kiện điều khiển và bạn đang đánh cắp kiểm soát khỏi vòng lặp chính gtk, do đó ngăn không cho nó xử lý các sự kiện cập nhật GUI bình thường.
Giải pháp đơn giản nhất bao gồm trên tạm thời cho kiểm soát trở lại GTK mỗi lần tiến độ được thay đổi:
while work_left:
...do something...
progressbar.set_fraction(...)
while gtk.events_pending():
gtk.main_iteration()
Chú ý rằng với giải pháp này, người dùng không thể thoát khỏi ứng dụng (gtk.main_quit sẽ không hoạt động vì vòng lặp mới [gtk.main_iteration()]) cho đến khi công việc nặng của bạn được thực hiện.
Một giải pháp khác bao gồm sử dụng các chức năng nhàn rỗi gtk, được gọi bởi vòng lặp chính gtk bất cứ khi nào nó không có gì để làm. Do đó, gtk nằm trong tầm kiểm soát và chức năng nhàn rỗi phải làm một chút công việc. Nó sẽ trả về True nếu có nhiều việc phải làm, nếu không thì False.
Giải pháp tốt nhất (không có nhược điểm) được James Henstridge chỉ ra. Nó đang tận dụng lợi thế của máy phát điện của python như các chức năng nhàn rỗi, để làm cho python tự động bảo toàn trạng thái cho chúng ta. Nó đi như thế này:
def my_task(data):
...some work...
while heavy_work_needed:
...do heavy work here...
progress_label.set_text(data) # here we update parts of UI
# there's more work, return True
yield True
# no more work, return False
yield False
def on_start_my_task_button_click(data):
task = my_task(data)
gobject.idle_add(task.next)
Các 'trong khi' ở trên chỉ là một ví dụ. Các quy tắc duy nhất là nó sẽ mang lại True sau khi làm một chút công việc và có nhiều việc phải làm, và nó phải mang lại False khi công việc được thực hiện.