Pregunta

Ok entonces tengo un QGraphicsScene en una clase llamada ojo.Llamo a una función:

void eye::playSequence(int sequenceNum) {

    for (int i=0; i<sequences[sequenceNum].numberOfSlides(); i++) {
        presentSlide(sequenceNum, i);
        time_t start;
            time(&start);
            bool cont=false;
            while (!cont) {
                time_t now;
                time(&now);
                double dif;
                dif=difftime(now, start);
                if (dif>5.0)
                    cont=true;
            }
    }
}

que para cada diapositiva llama:

void eye::presentSlide(int sequenceNum, int slideNum) {

    Slide * slide=sequences[sequenceNum].getSlide(slideNum);

    QGraphicsPixmapItem * pic0=scene.addPixmap(slide->getStimulus(0)->getImage());
    pic0->setPos(0,0);

    QGraphicsPixmapItem * pic1=scene.addPixmap(slide->getStimulus(1)->getImage());
    pic1->setPos(horizontalResolution-350,0);

    QGraphicsPixmapItem * pic2=scene.addPixmap(slide->getStimulus(2)->getImage());
    pic2->setPos(horizontalResolution-350,verticalResolution-450);

    QGraphicsPixmapItem * pic3=scene.addPixmap(slide->getStimulus(3)->getImage());
    pic3->setPos(0,verticalResolution-450);
}

Ahora, esperaría que esto mostrara un conjunto de imágenes, esperara 5 segundos, luego mostrara el siguiente, y así sucesivamente.En cambio, no muestra nada hasta que se hayan procesado todas las diapositivas y luego se muestren las últimas cuatro imágenes.he intentado llamar scene.update() en todos los lugares que pude imaginar y no hizo nada.Parece que la escena sólo se actualiza cuando el playSequence la función regresa.¿Alguna idea de lo que podría estar pasando aquí?

¿Fue útil?

Solución

Este es el tipo de comportamiento que se ve a menudo en los marcos por eventos GUI cuando uno quiere hacer animación continua. Voy a suponer que el ojo :: playSequence se llama desde un botón de clic o tal vez de algún momento durante el código de inicio de la aplicación? En cualquier caso, esto es lo que está pasando.

Qt utiliza el hilo principal de la aplicación para accionar un bucle de eventos. El bucle de eventos es algo como esto:

while(app_running)
{
  if(EventPending)
    ProcessNextEvent();
}

El problema que estamos viendo es que las actualizaciones de la pantalla se hacen durante un evento de pintura. Si está ejecutando un código durante un evento de clic del ratón o cualquier otro evento, entonces todo el dibujo que está haciendo está en cola y se elaborará a la pantalla en el próximo evento de pintura. A veces se necesita un tiempo para que esto se hunda.

La mejor manera de abordar esto es cambiar su enfoque un poco. Una forma es tirar su bucle while y configurar un QTimer establecido para disparar cada 5 segundos. En la ranura temporizador se puede dibujar una diapositiva. Cuando se activa el temporizador de nuevo, dibujan la siguiente diapositiva, etc.

Si desea una solución rápida más directo y menos elegante, intente llamar qapp-> processEvents () justo después de su llamada a presentSlide (sequenceNum, i). Esta (la mayor parte del tiempo) obligará a la aplicación para eliminar cualquier cola hasta eventos que deben incluir eventos de pintura.

También debería mencionar que el ojo :: presentSlide () es simplemente agregando nueva escena se opone a la escena en cada iteración que cubre las que se agregaron durante la última llamada. Piensa en la escena como una puerta de la nevera y cuando se llama a la escena () addXXX usted está lanzando más imanes de nevera en la puerta:.)

Otros consejos

Hay que dejar bucle de eventos de la aplicación se ejecute con el fin de mantener la interfaz de usuario actualizada. La forma más sencilla de hacer esto desde su código es llamar QApplication :: processEvents () en su bucle while interior.

Muchas personas considerarían el bucle while para ser ineficiente - después de todo, está a la espera de un período determinado de tiempo que transcurrirá. Es posible que desee pensar en la reestructuración de su código para utilizar un temporizador en su lugar.

Se puede crear un objeto QTimer en el constructor de la clase de ojo, establecer un tiempo de espera de 5 segundos, y conecte su señal de tiempo de espera () a una ranura en su clase de ojos que se actualiza el índice en el conjunto de diapositivas y llama presentSlide (). Se podría iniciar el temporizador en la función playSequence ().

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top