2009-04-03 3 views
3

좋아요. 그래서 QGraphicsScene이라는 눈이 있습니다. 각 슬라이드를 요구Qt : QGraphicsScene이 예상치를 업데이트하지 않습니다.

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

:

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

을 지금, 나는 그 다음을 표시 5 초 동안 기다리,이 이미지의 한 세트를 표시 할 것으로 예상, 그래서 것 내가 함수를 호출 에. 대신 모든 슬라이드가 처리 된 후 마지막 네 개의 이미지가 표시 될 때까지 아무 것도 표시하지 않습니다. 나는 화상을 찍을 수있는 모든 장소에서 scene.update()을 호출하려고 시도했지만 아무 것도하지 않았다. playSequence 함수가 반환 될 때 장면이 업데이트되는 것처럼 보입니다. 여기에 어떤 일이 벌어지고 있을지 모릅니다.

답변

7

이것은 연속 애니메이션을 수행하려는 경우 이벤트 기반 GUI 프레임 워크에서 자주 나타나는 종류의 동작입니다. eye :: playSequence는 버튼을 클릭하거나 어쩌면 응용 프로그램 시작 코드 중 일부 지점에서 호출 될 것이라고 추측 할 것입니다. 어쨌든, 여기에 무슨 일이 일어나고있는 것입니다.

Qt는 주 응용 프로그램 스레드를 사용하여 이벤트 루프를 만듭니다. 이벤트 루프는 다음과 같이이다 :

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

당신이보고있는 문제는 화면에 대한 업데이트는 페인트 이벤트 기간 동안 수행한다는 것이다. 마우스 클릭 이벤트 또는 다른 이벤트 중에 일부 코드를 실행하면 수행중인 모든 도면이 대기열에 올라서 다음 페인트 이벤트에서 화면에 그려집니다. 때로는 이것이 침몰하는 데 시간이 걸립니다.

가장 좋은 방법은 접근 방식을 약간 변경하는 것입니다. 한 가지 방법은 while 루프를 버리고 5 초마다 발사되도록 설정된 QTimer를 설정하는 것입니다. 타이머 슬롯에서 하나의 슬라이드를 그릴 수 있습니다. 타이머가 다시 발생하면 다음 슬라이드 등을 그립니다.

직접적이고 덜 우아한 빠른 수정을 원하면 presentSlide (sequenceNum, i) 호출 직후 qapp-> processEvents()를 호출 해보십시오. 이 (대부분의 경우) 애플리케이션은 페인트 이벤트를 포함해야하는 대기중인 모든 이벤트를 제거해야합니다.

또한 eye :: presentSlide()는 마지막 호출 중에 추가 된 장면을 다루는 장면마다 새 장면 객체를 추가하는 것임을 언급해야합니다. 장면을 냉장고 문으로 생각하고 scene()을 호출하면 addXXX 문에 더 많은 냉장고 자석을 던지게됩니다.

7

사용자 인터페이스를 계속 업데이트하려면 응용 프로그램의 이벤트 루프를 실행해야합니다. 코드에서이 작업을 수행하는 가장 쉬운 방법은 내부 while 루프에서 QApplication :: processEvents()를 호출하는 것입니다.

많은 사람들은 while 루프가 비효율적이라고 생각할 것입니다. 결국, 주어진 시간이 경과하기를 기다리는 것입니다. 대신 타이머를 사용하도록 코드를 재구성하는 것이 좋습니다.

아이 클래스의 생성자에서 QTimer 객체를 만들고 타임 아웃을 5 초로 설정하고 eye 클래스의 슬롯에 timeout() 신호를 연결하여 인덱스를 슬라이드 및 호출 집합으로 업데이트 할 수 있습니다 presentSlide(). playSequence() 함수에서 타이머를 시작합니다.