Pergunta

Ok, então eu tenho um QGraphicsScene em uma classe chamada olho. Eu chamo uma função:

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 chamadas de slides:

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

Agora, eu esperaria isso para exibir um conjunto de imagens, espere 5 segundos, em seguida, exibir o próximo, e assim por diante. Em vez disso, ele exibe nada até que todos os slides foram processados ??e, em seguida, os últimos quatro imagens são exibidas. Eu tentei ligar para scene.update() em cada lugar que eu poderia imagem e não fazer nada. Parece que a cena só atualiza quando a função playSequence retornos. Alguma idéia o que poderia estar acontecendo aqui?

Foi útil?

Solução

Este é o tipo de comportamento que é muitas vezes visto nos quadros GUI orientados a eventos quando se quer fazer animação contínua. Eu estou indo supor que o olho :: playSequence é chamado a partir de um clique de botão ou talvez de algum ponto durante o código de inicialização do aplicativo? Em todo caso, aqui é o que está acontecendo.

Qt usa o thread principal do aplicativo para dirigir um ciclo de eventos. O ciclo de eventos é algo como isto:

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

O problema que você está vendo é que as atualizações para a tela são feitas durante um evento de pintura. Se você estiver executando algum código durante um evento clique do mouse ou qualquer outro evento, em seguida, todo o desenho que você está fazendo está na fila e serão atraídos para a tela no próximo evento de pintura. Às vezes é preciso algum tempo para que isso afundar.

A melhor maneira de resolver isso é para mudar a sua abordagem um pouco. Uma maneira é jogar fora o seu loop while e configurar um conjunto QTimer para disparar a cada 5 segundos. No slot temporizador você pode desenhar um slide. Quando os fogos temporizador outra vez, chamar o próximo slide, etc.

Se você quer uma solução rápida mais direta e menos elegante, tente chamar qapp-> processEvents () logo após a sua chamada para presentSlide (sequenceNum, i). Este (a maioria do tempo) irá forçar o aplicativo para limpar todos os eventos na fila que deve incluir eventos de pintura.

Gostaria também de mencionar que o olho :: presentSlide () é apenas a adição de novos objetos de cena para a cena em cada iteração que abrange os que foram adicionados durante a última chamada. Pense na cena como uma porta de geladeira e quando você chamar cena () addXXX você está jogando mais imãs de geladeira na porta:.)

Outras dicas

Você precisa deixar ciclo de eventos do aplicativo executado, a fim de manter a interface de usuário atualizada. A maneira mais fácil de fazer isso do seu código é chamar QApplication :: processEvents () em seu loop while interior.

Muitas pessoas consideram o seu loop while ser ineficiente - afinal, você está apenas esperando por um determinado período de tempo a decorrer. Você pode querer pensar sobre a reestruturação seu código para usar um temporizador vez.

Você pode criar um objeto QTimer no construtor de sua classe olho, definir um tempo limite de 5 segundos e ligue o sinal de tempo limite () para um slot na sua classe olho que atualiza o índice para o conjunto de slides e chama presentSlide (). Você poderia começar o temporizador na função playSequence ().

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top