2010-01-12 7 views
14

Soy nuevo en QT. Entiendo que puedes forzar una actualización de la pantalla, pero me he quitado todo el pelo tratando de descubrir cómo. Esto es lo que estoy tratando de hacer específicamente.QT Repaint/Redraw/Update/Hacer algo

Presiono un botón (evento de señal Click), que ejecuta un código que cambia una imagen (QLabel) en la pantalla, espera la entrada, y luego continúa cambiando una nueva imagen (QLabel diferente). Lo intenté todo y la pantalla no se actualiza hasta que se completa el código de evento de la señal onclick. En este momento, no estoy esperando la entrada del usuario, estoy usando sleep (~ 500 ms) para realizar pruebas.

Según lo que he leído, QT está orientado a eventos, lo que significa que básicamente estoy creando un conjunto de eventos, que se ponen en una cola y se ejecutan cuando el evento de señal onClick vuelve al (lazo principal)/(controlador de eventos). No quiero esperar hasta que la función esté completa, hará que programar sea extremadamente doloroso si tengo que cumplir esta rutina completamente basada en eventos.

¿Cómo puedo forzar la actualización del mapa de píxeles de QLabel? He intentado todo. A continuación se muestra todo el código que he probado en mi controlador de eventos de señal onClick. (UpButton es el nombre de la QLabel que es un mapa de píxeles)

update(); 
repaint(); 
ui->upButton->setUpdatesEnabled(TRUE); 
update(); 
repaint(); 
QPaintEvent paintevent(ui->upButton->childrenRegion()); 
QPaintEvent * test = &paintevent; 
paintEvent(test); 
this->changeEvent(test); 
ui->upButton->update(); 
ui->upButton->repaint(); 
ui->upButton->repaint(ui->upButton->childrenRegion()); 
repaint(); 
QApplication::sendPostedEvents(); 
this->parentWidget()->update(); 
usleep(100000); 

Como se puede ver, sólo estoy dando palos de ciego en este punto. Intenté ver el código de muestra y hacer todos mis deberes, pero estoy perdido. Apreciar cualquier ayuda, consejo o código de muestra.

+2

En sistemas de GUI basados ​​en eventos, normalmente no "espera la entrada" en sus devoluciones de llamada. El estado de espera de entrada solo significa que estás en el ciclo de eventos. Así que estoy confundido acerca de por qué estarías usando el sueño para nada: ¿qué rutina pensabas llamar cuando * * tratabas con la entrada del usuario? No se preocupe porque los eventos sean dolorosos ... las señales y las ranuras no muerden (generalmente). – HostileFork

Respuesta

7

No debe esperar la entrada en su controlador de eventos. Debe replantearse la lógica de su programa para usar los eventos de la forma en que fueron diseñados. Todas las llamadas a update() y repaint() en su código son innecesarias si regresa al bucle de evento.

19

Estaba usando sleep para emular una breve cantidad de tiempo que la computadora estaba esperando que sucediera algo.

Como dije en mi pregunta, no quería usar eventos porque es un trabajo innecesario para lograr algo extremadamente simple.

Además, el 'evento' que debe tener lugar para que el programa continúe, es un evento USB. Dado que estoy usando un dispositivo de clase HID, no hay forma de configurar un evento sin un bucle de espera. Las clases USB HID no permiten configurar interrupciones, el sistema operativo reclama el dispositivo.

Logré hacer funcionar lo anterior. Caminé a través del depurador y noté que la pantalla se actualizaría antes de la función de reposo. Al ejecutar el programa de forma independiente, obtuve resultados aleatorios con la pantalla refrescando el 1% del tiempo. Me deshice de la función de suspensión y agregué algún otro código en su lugar para emular un retraso, y estuvo bien.

para el conocimiento de todos, esto es posible, no es prohibido, y es fácil de hacer con lo siguiente:

qApp->processEvents(); 

QAPP es una variable externa global en la cabecera QApplication.

Debido a que este evento USB está haciendo que mi flujo sea complicado, me encontré con la clase QWaitCondition. Iba a comenzar un proceso esperando el evento USB. Esperaría hasta que el proceso libere la condición de espera para que mi rutina continúe.

Pero si alguien piensa que esta es una mala idea, por favor, denuncie. Realmente aprecio tus comentarios PiedPiper y Hostile Fork.

Gracias.

2

Si entiendo correctamente, tiene una ranura y en esta ranura, actualiza la imagen que se muestra en una QLabel. Pero desea que este cambio se muestre antes de que la ranura finalice.

Si ese es el caso, emita un evento update() y llame a qApp-> processEvents(). Este método procesa los eventos que están esperando en la cola de eventos y luego regresa, por lo tanto, esto puede ser lo que está buscando.

PD: una actualización() puede no ser necesaria en absoluto, no estoy seguro.

2

Noté que a veces, cuando tienes varios widgets en capas, o widgets dentro de widgets, te ayuda a llamar a sus eventos repaint().

Por ejemplo

this->repaint(); 
this->parentWidget()->repaint(); 
this->parentWidget()->parentWidget()->repaint(); 

Esto es mucho más fácil luego empujando a cabo ningún tipo de procesamiento a otro hilo, o la creación de controladores de eventos adicionales.