문제

좋아, 그래서 난 a QGraphicsScene Eye라는 수업에서. 나는 함수를 호출한다 :

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 기능이 반환됩니다. 여기서 무슨 일이 일어나고 있는지 아이디어가 있습니까?

도움이 되었습니까?

해결책

이것은 연속 애니메이션을 원할 때 이벤트 중심 GUI 프레임 워크에서 종종 볼 수있는 행동입니다. 나는 그 눈 :: play equessence가 버튼 클릭에서 호출되었거나 응용 프로그램 시작 코드 중 어느 시점에서 호출 될 것입니까? 어쨌든 여기에 무슨 일이 일어나고 있는지.

QT는 기본 응용 프로그램 스레드를 사용하여 이벤트 루프를 구동합니다. 이벤트 루프는 다음과 같습니다.

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

당신이보고있는 문제는 화면에 대한 업데이트가 페인트 이벤트 중에 수행된다는 것입니다. 마우스 클릭 이벤트 나 다른 이벤트 중에 코드를 실행하는 경우 수행중인 모든 도면이 대기되어 다음 페인트 이벤트에서 화면으로 끌려 갈 것입니다. 때로는 이것이 침몰하는 데 시간이 오래 걸립니다.

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

보다 직접적이고 덜 우아한 빠른 수정을 원한다면 선물 슬라이드 (Sequencenum, I)를 호출 한 직후 Qapp-> ProcessEvents ()를 호출하십시오. 이 (대부분) 이것은 응용 프로그램이 페인트 이벤트를 포함하는 대기열 이벤트를 제거하도록 강요합니다.

또한 Eye :: PressentSlide ()는 마지막 호출 중에 추가 된 것들을 덮는 각 반복의 장면에 새로운 장면 객체를 추가하고 있다고 언급해야합니다. 장면을 냉장고 문으로 생각하고 장면 ()를 호출 할 때 addxxx는 문에 더 많은 냉장고 자석을 던지고 있습니다 :)

다른 팁

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

많은 사람들이 당신의 거친 루프가 비효율적이라고 생각할 것입니다. 결국, 당신은 주어진 시간을 경과하기 위해 기다리고 있습니다. 대신 타이머를 사용하도록 코드를 구조 조정하는 것에 대해 생각할 수 있습니다.

눈 등급의 생성자에서 QTIMER 객체를 생성하고 5 초의 시간 초과를 설정 한 다음 타임 아웃 () 신호를 눈 등급의 슬롯에 연결하여 인덱스를 슬라이드 세트로 업데이트하고 선물 슬라이드 ()를 호출 할 수 있습니다. PlaySequence () 함수에서 타이머를 시작합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top