2012-06-12 23 views
6

Utilizando Qt4.8 en un Mint Linux 12, implementé una ventana simple que contiene un QTableView para mostrar el contenido de un modelo. Los datos del modelo se actualizan continuamente (mensajes de registro) y la señal dataChanged() se emite regularmente (es decir, cada 100 ms).QWidget actualización de eventos pero no actualización visual

El problema que veo es el tartamudeo de las actualizaciones visuales sobre la mesa.

Instalé un filtro de eventos en la ventana que cuenta updateRequest -tipo de eventos, que deberían desencadenar un repintado de widget (también en widgets secundarios, es decir, el tableView). Estos vienen con un tiempo promedio de ~ 170 ms entre ellos y una desviación estándar de ~ 90 ms (que es bastante grande, supongo). Sin embargo, la tasa de actualización visual percibida es solo dos o tres veces por segundo y me pregunto por qué. Parece que no todos los eventos updateRequest desencadenan un repintado de widget o que el sistema de ventanas absorbe actualizaciones visuales.

Como segunda prueba, obligué a la ventana a actualizarse llamando al repaint o update cada 100 ms. Usando repaint, vi un aumento correspondiente en los eventos de tipo updateRequest y una disminución de la desviación estándar de los espacios; con update, el número no aumentó. Sin embargo, solo hubo un aumento moderado de la tasa de actualización percibida en ambos casos.

También: ¿Existe un buen método para medir la frecuencia con la que un widget se repinta realmente sin tener que sobrecargar su controlador paintEvent? Tal vez algo de QTest?


Actualización: Extendí mi filtro de eventos para capturar también paintEvent eventos de tipo. Solo hay un número de un dígito de aquellos contra> 1000 updateRequest -tipos de tipo.

Respuesta

1

Debe instrumentar las señales aboutToBlock() y awake() del despachador de eventos, y medir el tiempo entre ellas usando un QElapsedTimer. La instancia del despachador de eventos para el hilo actual es devuelta por el QAbstractEventDispatcher::instance() estático.

Si el bucle de evento duerme durante una fracción muy pequeña de su ventana de medición de tiempo, significa que hay demasiadas cosas sucediendo en el hilo de la GUI. Puede contar cuánto tiempo durmió el ciclo de eventos, por ejemplo, durante el último segundo. Si está por debajo del 10%, puede esperar actualizaciones lentas y otras cosas. Recuerde que los eventos de actualización están en cola con Qt::LowEventPriority. Serán reemplazados por señales en cola estándar y casi todos los demás eventos.

+0

¡Buena idea! Actualmente tengo un calendario apretado en cuanto a proyectos, por lo que tomará un par de días probarlo. Creo que esto debería darme una buena visión general de la carga, pero en realidad conté los eventos updateRequest que llegan a mi widget y se acercan mucho más (en promedio, la mente) que la tasa de actualización percibida. – arne

+0

El conteo está bien, pero no dice nada sobre el problema subyacente.Simplemente te dice que hay un problema, y ​​bueno, obviamente puedes notarlo sin escribir una sola línea de código :) –

0

QApplication::compressEvent descarta QEvent::UpdateRequest, si ya hay uno sin procesar. Por lo tanto, incluso los repintados pueden regresar inmediatamente sin pintar, si el evento se descarta. Puede verificar, si sus eventos updateRequest se descartan al sobrescribir compressEvent.

+0

Sé acerca de la compresión, pero ¿no se hace esto en el evento principal loop/QApplication en alguna parte? Pensé que si una updateRequest alcanza un widget, esto ya debería estar hecho. – arne

+0

Tiene razón, la compresión se realiza en EventLoop. Lo malentendí, donde cuentas los eventos. Y sí, si el evento alcanza el widget, la compresión ya está hecha. Por lo tanto, ignora mi respuesta. – Stefan

Cuestiones relacionadas