2012-06-12 23 views
6

Sử dụng Qt4.8 trên Mint Linux 12, tôi đã triển khai một cửa sổ đơn giản có chứa QTableView để hiển thị nội dung của mô hình. Dữ liệu mô hình được cập nhật liên tục (thông điệp tường trình) và tín hiệu dataChanged() được phát ra thường xuyên (tức là 100ms).Sự kiện cập nhật QWidget nhưng không cập nhật trực quan

Vấn đề tôi thấy là nói lắp các cập nhật trực quan trên bàn.

Tôi đã cài đặt bộ lọc sự kiện trên cửa sổ đếm updateRequest sự kiện loại, sẽ kích hoạt tô màu tiện ích con (cũng trên tiện ích con, ví dụ: tableView). Chúng đi vào với thời gian trung bình là ~ 170ms giữa chúng và độ lệch chuẩn là ~ 90ms (khá lớn, tôi đoán). Tuy nhiên, tỷ lệ cập nhật trực quan được nhận thức chỉ là hai hoặc ba lần một giây và tôi tự hỏi tại sao. Có vẻ như không phải tất cả sự kiện updateRequest đều kích hoạt tiện ích con hoặc hệ thống cửa sổ nuốt các cập nhật trực quan.

Là thử nghiệm thứ hai, tôi đã buộc cửa sổ tự cập nhật bằng cách gọi repaint hoặc update cứ 100ms một lần. Sử dụng repaint, tôi thấy mức tăng tương ứng trong các sự kiện loại updateRequest và giảm độ lệch chuẩn của khoảng trống; với số update, số không tăng. Tuy nhiên, chỉ có một sự gia tăng vừa phải của tỷ lệ cập nhật nhận thức trong cả hai trường hợp.

Ngoài ra: Có phương pháp hay nào để đo tần suất một tiện ích thực sự thực sự được sơn lại mà không phải quá tải bộ xử lý paintEvent không? Có lẽ một cái gì đó từ QTest?


Cập nhật: tôi mở rộng bộ lọc sự kiện của tôi cũng bắt paintEvent sự kiện -loại. Chỉ có một số có một chữ số so với 1000 sự kiện loại 1000 updateRequest.

Trả lời

1

Bạn nên sử dụng tín hiệu aboutToBlock()awake() của người điều phối sự kiện và đo thời gian giữa chúng bằng cách sử dụng QElapsedTimer. Ví dụ của trình điều phối sự kiện cho luồng hiện tại được trả về bởi static QAbstractEventDispatcher::instance().

Nếu vòng lặp sự kiện chỉ chiếm một phần rất nhỏ trong thời lượng đo thời gian của bạn, điều đó có nghĩa là có quá nhiều thứ đang diễn ra trong luồng GUI. Bạn có thể đếm số vòng lặp sự kiện trong bao lâu, trong khoảng giây cuối cùng. Nếu dưới 10%, bạn có thể mong đợi các cập nhật chậm và không có gì. Hãy nhớ rằng các sự kiện cập nhật được xếp hàng đợi với Qt::LowEventPriority. Chúng sẽ được kiểm soát trước bởi các tín hiệu xếp hàng tiêu chuẩn và gần như tất cả các sự kiện khác.

+0

Ý tưởng hay! Tôi hiện đang trên một lịch trình chặt chẽ dự án khôn ngoan, vì vậy nó sẽ mất một vài ngày để kiểm tra này. Tôi nghĩ rằng điều này sẽ cho tôi một cái nhìn tổng quan tốt về tải, nhưng tôi thực sự đếm các sự kiện updateRequest mà đạt được widget của tôi và những người đến gần hơn nhiều (trung bình, tâm trí) so với tỷ lệ cập nhật nhận thức. – arne

+0

Việc đếm là tốt, nhưng nó không cho bạn biết bất cứ điều gì về vấn đề cơ bản.Nó chỉ cho bạn biết có một vấn đề, và tốt, bạn rõ ràng có thể nhận thấy nó mà không cần viết một dòng mã :) –

0

QApplication::compressEvent loại bỏ QEvent::UpdateRequest, nếu đã có một chưa được xử lý. Vì vậy, ngay cả repaint (s) có thể trở lại ngay lập tức mà không cần sơn, nếu sự kiện này bị loại bỏ. Bạn có thể kiểm tra, nếu sự kiện updateRequest của bạn bị hủy bằng cách ghi đè compressEvent.

+0

Tôi biết về nén, nhưng điều này không được thực hiện trong vòng lặp sự kiện chính/QApplication ở đâu đó? Tôi nghĩ rằng nếu một updateRequest đạt đến một widget, điều này nên đã được thực hiện. – arne

+0

Bạn nói đúng, quá trình nén được thực hiện trong EventLoop. Tôi hiểu lầm, nơi bạn đếm các sự kiện. Và vâng, nếu sự kiện đến tiện ích con, quá trình nén đã hoàn tất. Vì vậy, bỏ qua câu trả lời của tôi. – Stefan