Question

Ok donc j'ai un QGraphicsScene dans une classe appelée oeil. J'appelle une fonction:

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;
            }
    }
}

qui, pour chaque appels de diapositives:

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);
}

Maintenant, je me attends à cette option pour afficher un ensemble d'images, attendez 5 secondes, puis afficher la suivante, et ainsi de suite. , Il affiche au lieu rien jusqu'à ce que toutes les diapositives ont été traitées et les quatre dernières images sont affichées. Je l'ai essayé d'appeler scene.update() dans chaque endroit où je pouvais l'image et ne rien faire. Il semble que la scène met à jour que lorsque la fonction retourne de playSequence. Toutes les idées ce qui pourrait se passer ici?

Était-ce utile?

La solution

Ceci est le genre de comportement qui est souvent vu dans les cadres de l'interface graphique événementielles lorsque l'on veut faire de l'animation continue. Je vais deviner que l'oeil :: playSequence est appelé à partir d'un bouton clic ou peut-être d'un point au cours du code de démarrage de l'application? Dans tous les cas, voici ce qui se passe.

Qt utilise le thread d'application principal pour piloter une boucle d'événements. La boucle d'événement est quelque chose comme ceci:

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

Le problème que vous voyez est que les mises à jour à l'écran sont faites lors d'un événement de peinture. Si vous utilisez un code lors d'un événement de clic de souris ou tout autre événement, alors tout le dessin que vous faites est mis en attente et sera dessiné à l'écran sur le prochain événement de peinture. Parfois, il faut un certain temps pour que cela se couler dans.

La meilleure façon de répondre est de changer votre approche un peu. Une façon est de jeter votre boucle while et la configuration d'un QTimer mis à feu toutes les 5 secondes. Dans la fente de la minuterie, vous pouvez dessiner une diapositive. Quand à nouveau les feux de minuterie, dessiner la diapositive suivante, etc.

Si vous voulez une solution rapide plus directe et moins élégante, essayez d'appeler qapp-> processEvents () juste après votre appel à presentSlide (SequenceNum, i). Ce (la plupart du temps) forcera l'application à effacer tout les événements qui faisaient la queue devrait inclure des événements de peinture.

Je dois aussi mentionner que les yeux :: presentSlide () est simplement d'ajouter de nouveaux objets scène à la scène à chaque itération couvrant ceux qui ont été ajoutés au cours du dernier appel. Pensez à la scène comme une scène () porte du réfrigérateur et lorsque vous appelez addXXX vous jetez plus aimants sur la porte.)

Autres conseils

Vous devez laisser la boucle d'événements de l'application d'exécution afin de garder l'interface utilisateur mise à jour. La meilleure façon de le faire à partir de votre code est d'appeler QApplication :: processEvents () dans votre boucle while intérieure.

Beaucoup de gens considèrent votre boucle while inefficace - après tout, vous qui attendent une certaine période de temps pour écouler. Vous voudrez peut-être penser à la restructuration de votre code à utiliser à la place une minuterie.

Vous pouvez créer un objet QTimer dans votre constructeur de la classe des yeux, définir un délai de 5 secondes, et connectez le signal délai d'attente () à un emplacement dans votre classe oeil qui met à jour l'index dans l'ensemble des diapositives et appelle presentSlide (). Vous commencez la minuterie dans la fonction playSequence ().

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top