Frage

Ok, so habe ich eine QGraphicsScene in einer Klasse namens Auge bekam. Ich nenne eine Funktion:

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

, die für jede Folie Anrufe:

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

Nun, ich würde erwarten, dass dies einen Satz von Bildern angezeigt werden, für 5 Sekunden warten, dann die nächste Anzeige, und so weiter. Stattdessen zeigt es nichts, bis alle Folien verarbeitet wurden und dann die letzten vier Bilder angezeigt werden. Ich habe versucht Aufruf scene.update() an jedem Ort konnte ich Bild und es tut nichts. Es scheint, wie die Szene nur aktualisiert, wenn die playSequence Funktion zurückkehrt. Irgendwelche Ideen, was könnte denn hier los?

War es hilfreich?

Lösung

Dies ist die Art von Verhalten, das oft in ereignisgesteuerten GUI-Frameworks gesehen wird, wenn man will, kontinuierliche Animation tun. Ich werde dieses Auge erraten :: playSequence von einem Button-Klick aufgerufen wird, oder vielleicht von einem gewissen Punkt während der Anwendung Startcode? In jedem Fall ist hier was los ist.

Qt verwendet das Hauptanwendungsthread eine Ereignisschleife zu treiben. Die Ereignisschleife ist so etwas wie folgt aus:

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

Das Problem ist, dass Sie sehen, dass Updates auf den Bildschirm während eines Paint-Ereignisses fertig ist. Wenn Sie einen Code während einer Mausklickereignis oder ein anderes Ereignis ausgeführt werden, dann werden alle die Zeichnung auf Sie tun Warteschlange gestellt und wird auf dem Bildschirm auf die nächste Farbe Ereignis gezogen werden. Manchmal dauert es eine Weile, dies zu versenken.

Der beste Weg, dies zu adressieren ist Ihr Ansatz ein wenig zu ändern. Eine Möglichkeit ist, Ihre while-Schleife und das Setup eines QTimer gesetzt wegzuwerfen alle 5 Sekunden zu schießen. Im Timer-Steckplatz können Sie eine Folie ziehen. Wenn der Zeitgeber erneut ausgelöst wird, die nächste Folie ziehen, etc.

Wenn Sie eine direktere und weniger elegant schnelle Lösung wollen, versuchen Sie fordern qapp-> process () direkt nach dem Aufruf von presentSlide (sequenceNum, i). Das (die meiste Zeit) wird die Anwendung zwingen, zu löschen jedes Ereignis Warteschlange gestellt, die sollten Farbe Ereignisse umfassen.

Ich sollte auch dieses Auge erwähnen :: presentSlide () nur ist das Hinzufügen von neuen Szene bei jeder Iteration, um die Szene Objekte diejenigen abdeckt, die während des letzten Aufrufs hinzugefügt wurden. Denken Sie an die Szene als Kühlschranktür und wenn Sie Szene () aufrufen addXXX Sie werfen mehr Kühlschrankmagnete an der Tür.)

Andere Tipps

Sie müssen den Antrag der Ereignisschleife aktualisiert, um die Benutzeroberfläche zu halten laufen lassen. Der einfachste Weg, dies aus dem Code zu tun ist, QApplication :: process () in der inneren while-Schleife zu nennen.

Viele Leute würden Ihre while-Schleife betrachten ineffizient zu sein - schließlich sind Sie nur für einen bestimmten Zeitraum warten verstreichen. Sie können über die Umstrukturierung des Code zu denken, anstatt einen Timer zu verwenden.

Sie könnten ein QTimer Objekt im Auge Klasse Konstruktor erstellen, legen Sie ein Timeout von 5 Sekunden und schließen Sie das Timeout (Signal) zu einem Schlitz in Ihrem Auge Klasse, die den Index in den Satz von Dias aktualisiert und rufe presentSlide (). Sie würden die Timer in der playSequence () Funktion starten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top