2012-09-07 18 views
5

मैं दिखाई एनिमेशन अनुक्रमिक बनाने की कोशिश कर रहा हूँ। मेरे पास जावास्क्रिप्ट फ़ंक्शन है, जो myModel.move() को दो बार कॉल करता है। मेरे पास MyModel दिखाने के लिए एक ग्रिड व्यू है और मेरे पास "एक्स पर व्यवहार" एनीमेशन है, इस प्रकार मैं दृश्यों को देख सकता हूं। लेकिन, दोनों आंदोलन एनिमेटन paralell में चलाता है (उनके बीच छोटी देरी ध्यान देने योग्य नहीं है)।QML: जब तक प्रतीक्षा करें एनिमेशन समाप्त

मेरा विचार है कि कितने एनिमेशन शुरू किया गया था के एक काउंटर जोड़ने के लिए था और उनमें से कितने पहले से ही समाप्त हो गया। कुछ इस तरह;

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

यह अपेक्षा के अनुसार काम करता है। फिर, जब तक सभी एनिमेशन समाप्त नहीं हो जाते, तब तक मैं अपने जावास्क्रिप्ट फ़ंक्शन में एक लूप जोड़ता हूं।

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

यहां समस्या है। मैं देख सकता हूं कि पहले कदम() के बाद सभी आवश्यक एनिमेशन शुरू हो गए, लेकिन कुछ भी नहीं देखा जा सकता और कोई भी एनीमेशन समाप्त नहीं हुआ। मेरे पास कुछ प्रकार का डेडलॉक है। इसे कैसे हल करें?

उत्तर

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

मैं जावास्क्रिप्ट के साथ अच्छा नहीं हूँ। लेकिन आप व्यस्त लूप क्यों करते हैं? मैं 2 कार्यों का निर्माण करूंगा।

  • पहले एक myModel.move() करना होगा, फिर
  • जब भविष्य घटना बनाई गई है दूसरा एक बुलाया जाएगा (एक छिपा बटन जो क्लिक किया जाएगा बनाने की तरह) एक भविष्य घटना के लिए क्षेत्र तैयार करते हैं। ऊपर दिए गए उदाहरण के साथ यह Onclick होगा।

ऐसा लगता है कि onRunningChanged ईवेंट हैंडलर की एक परिभाषा है। क्यों एक ही बनाने नहीं, चलो यह onModelIdle फोन की तरह

... 
    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

हाँ, मुझे पता है ... सरलीकृत सवाल सरलीकृत जवाब उत्पादन :-(वास्तव में, मैं कई लगातार विभिन्न myModel.move (...) के लिए (चाहते हैं कॉल। हालांकि, अपने सुझाव प्रयोग करने योग्य है देखना समाधान मैं नीचे पोस्ट)। – meolic

+0

एक व्यस्त पाश एक अच्छा विचार है अगर आप प्रदर्शन बनाए रखना चाहते हैं नहीं है। – trusktr

+0

@trusktr और जहाँ आप देखते हैं मैं कहना है कि यह एक अच्छा विचार है? – UmNyobe

1

यहाँ एक काम #UmNyobe से उत्तर के आधार पर समाधान है। खैर, क्यूएमएल एक घोषणात्मक भाषा है और इस प्रकार पुनरावृत्तियों की समस्याओं के लिए समस्याग्रस्त है। किसी भी टिप्पणी का स्वागत है। शायद, कोई बेहतर (अधिक पठनीय) शुद्ध क्यूएमएल प्रोग्राम सुझा सकता है जो एक ही प्रभाव उत्पन्न करेगा।

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() 
         } 
        } 
       } 
      } 
     } 
    } 
} 
संबंधित मुद्दे