2014-09-27 60 views
3

過渡動畫完成後,我想更改狀態。我有以下的代碼實現了這一點,但它似乎有種的hackish:過渡動畫完成後更改狀態

import QtQuick 2.3 
import QtQuick.Controls 1.2 
import QtQuick.Controls.Styles 1.2 

Rectangle { 
    id: root 
    width: 400 
    height: 400 

    Rectangle { 
     id: rect 
     color: "blue" 
     width: 50 
     height: 50 
     anchors.centerIn: parent 

     MouseArea { 
      anchors.fill: parent 
      onClicked: rect.state = "animating" 
     } 

     states: [ 
      State { 
       name: "animating" 

       PropertyChanges { 
        target: rect 
        rotation: 360 
       } 
      }, 
      State { 
       name: "shrinking" 

       PropertyChanges { 
        target: rect 
        scale: 0 
       } 
      } 
     ] 

     transitions: [ 
      Transition { 
       from: "" 
       to: "animating" 

       SequentialAnimation { 
        RotationAnimation { 
         duration: 500 
        } 
        ScriptAction { 
         script: rect.state = "shrinking" 
        } 
       } 
      }, 
      Transition { 
       from: "animating" 
       to: "shrinking" 

       NumberAnimation { 
        property: "scale" 
        duration: 500 
       } 
      } 
     ] 
    } 
} 

有沒有一個更好的辦法做到這一點,而無需使用ScriptAction?請注意,我需要第二個狀態,並且我不想將縮放動畫合併到animating轉換的SequentialAnimation中。

+0

這個問題是https://stackoverflow.com/questions/22902769/how-to-switch-to-another-state-at-的副本q-transition-in-qml,但您的現有解決方案比原始問題的答案更清晰。 – cmannett85 2014-09-27 09:45:00

+0

我甚至不喜歡我的解決方案,所以我希望有更好的解決方案。 :p – Mitch 2014-09-27 10:15:57

+0

事實上,你的國家被命名爲「縮小」而不是「縮小」,這表明它們不是真實狀態,而是過渡作爲狀態實施。你不能用SequentialAnimation合併兩個轉換嗎? – jturcotte 2014-09-28 12:33:11

回答

-1

略微不同的方法是設置在animating狀態shrinking狀態,並使用一個PropertyAction迫使狀態改變在過渡結束時發生:

 State { 
      name: "animating" 

      PropertyChanges { 
       target: rect 
       rotation: 360 
      } 
      PropertyChanges { 
       target: rect 
       state: "shrinking" 
      } 

 Transition { 
      SequentialAnimation { 
       RotationAnimation { 
        duration: 500 
       } 
       PropertyAction { 
        target: rect 
        property: "state" 
       } 
      } 
     } 

請注意,我同意jturcotte對他在這裏使用這些狀態的評估。

+0

這不起作用:'QML StateGroup:不能將狀態更改作爲狀態定義的一部分應用。' – Mitch 2015-09-08 19:09:07

+0

不知道這對項目本身的狀態更改不起作用(儘管有意義) 。我經常使用這種方法,根項目觸發各種兒童狀態變化時的狀態變化。您仍然可以通過例如使用兩個helper'Item','shrinkstate'和'animatingstate',定義那裏的狀態變化,然後從父矩形觸發它們的狀態變化。這裏非常麻煩,但如果qml和狀態更改的其餘部分變得更加複雜,可以是更清潔的解決方案。 – Adversus 2015-09-10 06:55:44

0

正確的方法是在運行pass爲false而不是完成動畫時更改轉換的runningChanged處理程序中的狀態。 這樣做,你有兩種解決方法:

索爾1.使用connections(你會得到一個關於沒有呈報財產警告,忽略它)

Connections{ 
      target:rect.transitions[0] 

      onRunningChanged:{ 
       if(rect.transitions[0].running === false) 
       { 
        rect.state = "shrinking" 
       } 
      } 
     } 

的代碼將是:

import QtQuick 2.3 
import QtQuick.Controls 1.2 
import QtQuick.Controls.Styles 1.2 

Rectangle { 
    id: root 
    width: 400 
    height: 400 

    Rectangle { 
     id: rect 
     color: "blue" 
     width: 50 
     height: 50 
     anchors.centerIn: parent 

     MouseArea { 
      anchors.fill: parent 
      onClicked: rect.state = "animating" 
     } 

     states: [ 
      State { 
       name: "animating" 

       PropertyChanges { 
        target: rect 
        rotation: 360 
       } 
      }, 
      State { 
       name: "shrinking" 

       PropertyChanges { 
        target: rect 
        scale: 0 
       } 
      } 
     ] 
     Connections{ 
      target:rect.transitions[0] 

      onRunningChanged:{ 
       if(rect.transitions[0].running === false) 
       { 
        rect.state = "shrinking" 
       } 
      } 
     } 
     transitions: [ 
      Transition { 
       from: "" 
       to: "animating" 
        RotationAnimation { 
         duration: 500 
        } 
      }, 
      Transition { 
       from: "animating" 
       to: "shrinking" 

       NumberAnimation { 
        property: "scale" 
        duration: 500 
       } 
      } 
     ] 
    } 
} 

溶液2:

import QtQuick 2.3 
import QtQuick.Controls 1.2 
import QtQuick.Controls.Styles 1.2 

Rectangle { 
    id: root 
    width: 400 
    height: 400 

    Rectangle { 
     id: rect 
     color: "blue" 
     width: 50 
     height: 50 
     anchors.centerIn: parent 

     MouseArea { 
      anchors.fill: parent 
      onClicked: rect.state = "animating" 
     } 

     states: [ 
      State { 
       name: "animating" 

       PropertyChanges { 
        target: rect 
        rotation: 360 
       } 
      }, 
      State { 
       name: "shrinking" 

       PropertyChanges { 
        target: rect 
        scale: 0 
       } 
      } 
     ] 

     transitions: [ 
      Transition { 
       from: "" 
       to: "animating" 

        RotationAnimation { 
         duration: 500 
        } 
        onRunningChanged:{ 
         if(running === false) 
         { 
          rect.state = "shrinking" 
         } 
        } 
      }, 
      Transition { 
       from: "animating" 
       to: "shrinking" 

       NumberAnimation { 
        property: "scale" 
        duration: 500 
       } 
      } 
     ] 
    } 
} 
: 在 runningchanged處理程序中直接過渡改變狀態

我更喜歡第一個解決方案(Connections)的原因,而是更通用的

+0

我不會稱這是正確的方式,就像我的解決方案不適合。我仍然不認爲有這樣做的好方法。 – Mitch 2015-09-08 18:55:19

+0

我的意思是正確的方式,我認爲Qt的開發者創建的信號runningChanged就像那樣使用,比使用ScriptAction更好。如果不是發射這個信號的點是什麼:) – Mido 2015-09-08 18:57:43

+1

改變狀態有很多種方法,但它們要麼全都是命令性的,而不是聲明性的,或者他們只是覺得......太狡猾了。 :p我認爲''nextState'屬性在'State'對象中是非常好的。但是我需要提出一個更好的例子,因爲我認爲@jturcotte對我的原創作品是正確的,因爲它可能只是兩個動畫。 – Mitch 2015-09-08 19:03:07