Domanda

Ok, quindi ho una QGraphicsScene in un occhio classe chiamata. Chiamo una funzione:

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

che per ogni chiamata di scorrimento:

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

Ora, mi sarei aspettato questo per visualizzare una serie di immagini, attendere 5 secondi, quindi visualizzare il successivo, e così via. Invece, visualizza nulla finché tutti i vetrini sono stati processati e poi vengono visualizzati gli ultimi quattro immagini. Ho provato a chiamare scene.update() in ogni luogo ho potuto immagine e non ha fatto nulla. Sembra che la scena aggiorna solo quando la funzione ritorna playSequence. Tutte le idee che potrebbero essere succedendo qui?

È stato utile?

Soluzione

Questo è il tipo di comportamento che è spesso visto in Event Driven framework GUI quando si vuole fare animazione continua. Io vado a indovinare che l'occhio :: playSequence viene chiamato da un pulsante di scatto o forse da un certo punto durante il codice di avvio dell'applicazione? In ogni caso, ecco cosa sta succedendo.

Qt utilizza il filo principale per comandare un ciclo di eventi. Il ciclo di eventi è qualcosa di simile:

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

Il problema che state vedendo è che gli aggiornamenti dello schermo sono fatte nel corso di un evento di vernice. Se si esegue del codice nel corso di un evento di clic del mouse o qualsiasi altro evento, allora tutto il disegno che si sta facendo è in coda e sarà attirata lo schermo sul prossimo evento vernice. A volte ci vuole un po 'per questo affondare in.

Il modo migliore per affrontare questo è quello di cambiare il vostro approccio un po '. Un modo è quello di buttare via il ciclo while e la configurazione di un QTimer set di sparare ogni 5 secondi. Nello slot del timer è possibile disegnare una diapositiva. Quando il timer incendi ancora una volta, traggono la diapositiva successiva, ecc.

Se si desidera una soluzione rapida più diretto e meno elegante, provare a chiamare qapp-> processEvents () subito dopo la chiamata a presentSlide (SequenceNum, i). Questo (il più delle volte) forzerà l'applicazione per cancellare qualsiasi coda gli eventi che dovrebbero includere eventi di vernice.

Vorrei anche ricordare che l'occhio :: presentSlide () è semplicemente l'aggiunta di nuovi oggetti di scena per la scena ad ogni iterazione coprire quelli che sono stati aggiunti durante l'ultima chiamata. Pensi della scena come una porta del frigorifero e quando si chiama scena () addXXX si sta gettando più magneti frigo sulla porta:.)

Altri suggerimenti

È necessario lasciare ciclo di eventi dell'applicazione eseguita al fine di mantenere l'interfaccia utente aggiornata. Il modo più semplice per farlo dal codice è quello di chiamare QApplication :: processEvents () nel ciclo while interno.

Molte persone considerano il vostro ciclo while per essere inefficiente - dopo tutto, si sono solo in attesa di un determinato periodo di tempo che deve trascorrere. Si consiglia di pensare di ristrutturazione il codice per utilizzare un timer, invece.

Si potrebbe creare un oggetto QTimer nel costruttore della classe di occhio, impostare un timeout di 5 secondi, e collegare il suo segnale di timeout () per una fessura nella tua classe occhio che aggiorna l'indice nella serie di diapositive e invita presentSlide (). Si potrebbe avviare il timer nella funzione playSequence ().

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top