2012-09-07 16 views
5

Sto cercando di rendere sequenziali le animazioni visibili. Ho una funzione javascript, che chiama myModel.move() due volte. Ho un GridView per mostrare myModel e ho animazione "Comportamento su x", quindi posso vedere i movimenti visivamente. Ma entrambi gli animatori di movimento sono in parallelo (il piccolo ritardo tra loro non è evidente).QML: attendere fino al termine delle animazioni

La mia idea era di aggiungere un contatore di quante animazioni erano state avviate e quante di esse erano già finite. Qualcosa come questo;

Behavior on x { 
    NumberAnimation { 
     id: animationX; 
     duration: 500; 
     onRunningChanged: { 
      if (animationX.running) { 
       console.log("Animation start"); 
       myModel.busy = myModel.busy + 1 
      } else { 
       console.log("Animation stop"); 
       myModel.busy = myModel.busy - 1 
      } 
     } 
    } 
} 

Funziona come previsto. Quindi, aggiungo un ciclo alla mia funzione javascript per attendere fino a quando tutte le animazioni sono terminate.

ListModel { 
    id: myModel 
    property int busy: 0 
    function doSomething() { 
     myModel.move(...) 
     while (myModel.busy) {} 
     myModel.move(...) 
    } 
} 

Ecco il problema. Vedo che dopo la prima mossa() sono iniziate tutte le animazioni necessarie, ma non è possibile vedere nulla e nessuna animazione completata. Ho una specie di situazione di stallo. Come risolvere questo?

risposta

2
function doSomething() { 
    myModel.move(...) 
    while (myModel.busy) {} 
    myModel.move(...) 
} 

Non sto bene con javascript. Ma perché sei impegnato? Vorrei creare 2 funzioni.

  • Il primo a rendere myModel.move(), quindi preparare il campo per un evento futuro (come la creazione di un pulsante nascosto che verrà cliccato)
  • Il secondo verrà chiamato quando si crea l'evento futuro. Con l'esempio sopra sarà Onclick.

Sembra che onRunningChanged sia una definizione di gestore eventi. Perché non creare lo stesso, consente di chiamare onModelIdle come

... 
    onRunningChanged: { 
     if (animationX.running) { 
      console.log("Animation start"); 
      myModel.busy = myModel.busy + 1 
     } else { 
      console.log("Animation stop"); 
      myModel.busy = myModel.busy - 1 
      if(myModel.busy == 0) 
       // don't know the code, but trigger the onModelIdle event which 
       // be handled below 
     } 
    } 
... 

ListModel { 
    id: myModel 
    ... 

    onModelIdle{ 
     myModel.move(...) 
    } 
} 
+0

Sì, lo so ... domande semplificate producono risposte semplificate :-(In realtà, voglio avere molti myModel.move consecutivi diverso (...) chiamate. Tuttavia, il suggerimento è utilizzabile (vedi soluzione che ho postato sotto) – meolic

+0

Un ciclo occupato non è una buona idea se si desidera mantenere le prestazioni – trusktr

+0

@trusktr e dove vedi dico che è una buona idea? – UmNyobe

1

Ecco una soluzione di lavoro in base alla risposta da #UmNyobe. Bene, QML è un linguaggio dichiarativo e quindi problematico per problemi iterativi. Qualsiasi commento è gradito. Forse, qualcuno può suggerire un programma QML puro migliore (più leggibile) che produca lo stesso effetto.

import QtQuick 1.1 
GridView { 
    id: mainGrid 
    cellWidth: 165; cellHeight: 95 
    width: 5*cellWidth; height: 4*cellHeight 
    model: myModel 
    delegate: myButton 
    property string animate: "no" 
    property int busy: 0 
    signal busyPlus 
    signal busyMinus 
    onBusyPlus: { 
     busy++ 
    } 
    onBusyMinus: { 
     busy-- 
     if (busy == 0) mainGrid.model.algorithm() 
    } 
    ListModel { 
     id: myModel 
     property int step: 0 
     property int one: 0 
     function createModel() { 
      for (var i=1; i<=20; i++) { 
       append({"display": i}) 
      } 
     } 
     function algorithm() { 
      if (step == 0) { 
       move(0,19,1) 
       one = 0 
       step++ 
      } 
      else if (step == 1) { 
       if (one < 19) { 
        move(one,one+1,1) 
        one++ 
        if (one == 19) step++ 
       } 
      } 
      else if (step == 2) { 
       move(0,1,1) 
       move(5,6,1) 
       move(10,11,1) 
       move(15,16,1) 
       step++ 
      } 
     } 
     Component.onCompleted: { 
      createModel() 
      mainGrid.animate = "yes" 
      algorithm() 
     } 
    } 
    Component { 
     id: myButton 
     Item { 
      id: item 
      width: mainGrid.cellWidth-5; height: mainGrid.cellHeight-5; 
      Rectangle { 
       id: box 
       parent: mainGrid 
       x: item.x; y: item.y; 
       width: item.width; height: item.height; 
       border.width: 1 
       Text { 
        anchors.centerIn: parent 
        text: display 
        font.pixelSize: 48 
       } 
       Behavior on x { 
        enabled: mainGrid.animate == "yes" 
        NumberAnimation { 
         id: animationX; 
         duration: 1000; 
         onRunningChanged: { 
          if (animationX.running) mainGrid.busyPlus() 
          else mainGrid.busyMinus() 
         } 
        } 
       } 
       Behavior on y { 
        enabled: mainGrid.animate == "yes" 
        NumberAnimation { 
         id: animationY; 
         duration: 1000; 
         onRunningChanged: { 
          if (animationY.running) mainGrid.busyPlus() 
          else mainGrid.busyMinus() 
         } 
        } 
       } 
      } 
     } 
    } 
} 
Problemi correlati