2017-03-24 90 views
0

我想要改變其依賴的畫面和色彩上狀態的圖標組成:創建QML美國動態

StateIcon.qml:

import QtQuick 2.0 
import QtQuick.Layouts 1.3 
import QtGraphicalEffects 1.0 

Item { 
    Layout.preferredWidth: appLayout.icon.prefWidth 
    Layout.preferredHeight: appLayout.icon.prefHeight 

    property variant stateImage: stateImageInstance 
    Image { 
     id: stateImageInstance 
     width: appLayout.icon.prefWidth 
     height: appLayout.icon.prefWidth 

     sourceSize.width: width 
     sourceSize.height: height 
    } 

    property variant imageOverlay: imageOverlayInstance 
    ColorOverlay { 
     id: imageOverlayInstance 
     anchors.fill: stateImage 
     source: stateImage 
    } 

    transitions: Transition { 
     SequentialAnimation { 
      NumberAnimation { 
       target: stateImage; property: "scale" 
       to: 0; duration: 100 
      } 
      PropertyAction { 
       target: stateImage; property: "source" 
      } 
      PropertyAction { 
       target: imageOverlay; property: "color" 
      } 
      NumberAnimation { 
       target: stateImage; property: "scale" 
       to: 1; duration: 100 
      } 
     } 
    } 
} 

的問題是,我在組件實例來定義狀態:

main.qml:

StateIcon { 
    id: stateIcon 
    states: [ 
     State { 
      name: "state1"; 
      PropertyChanges { 
       target: stateIcon.stateImage 
       source: "qrc:/resources/icons/icon1.svg" 
      } 
      PropertyChanges { 
       target: stateIcon.imageOverlay; color: "gray" 
      } 

     }, 
     State { 
      name: "state2"; 
      PropertyChanges { 
       target: stateIcon.stateImage 
       source: "qrc:/resources/icons/icon2.svg" 
      } 
      PropertyChanges { 
       target: stateIcon.imageOverlay; color: "green" 
      } 
     } 
     ... 
    ] 

    state: "state1" 
} 

現在我想知道的是它可能只定義狀態名稱,顏色和源在某些陣列:

main.qml:

StateIcon { 
    id: stateIcon 
    rawStates: [ 
      { 
       name: "state1", 
       iconSource: "qrc:/resources/icons/state1.svg", 
       color: "green" 
      }, 
      { 
       name: "state2", 
       iconSource: "qrc:/resources/icons/state2.svg", 
       color: "green" 
      }, 
      ... 
     ] 

    state: "state1" 
} 

而在StateIcon.qml定義states財產使用動態rawStates財產?

也許這樣的事情:

StateIcon.qml:

import QtQuick 2.0 
import QtQuick.Layouts 1.3 
import QtGraphicalEffects 1.0 

Item { 
    property variant rawStates 

    Layout.preferredWidth: appLayout.icon.prefWidth 
    Layout.preferredHeight: appLayout.icon.prefHeight 

    Image { 
     id: stateImage 
     width: appLayout.icon.prefWidth 
     height: appLayout.icon.prefWidth 

     sourceSize.width: width 
     sourceSize.height: height 
    } 

    ColorOverlay { 
     id: imageOverlay 
     anchors.fill: stateImage 
     source: stateImage 
    } 

    states: [ 
     for(var i=0; i<rawStates.length; ++i) { 
      ? 
     } 
    ] 

    transitions: Transition { 
     SequentialAnimation { 
      NumberAnimation { 
       target: stateImage; property: "scale" 
       to: 0; duration: 100 
      } 
      PropertyAction { 
       target: stateImage; property: "source" 
      } 
      PropertyAction { 
       target: imageOverlay; property: "color" 
      } 
      NumberAnimation { 
       target: stateImage; property: "scale" 
       to: 1; duration: 100 
      } 
     } 
    } 
} 
+1

您是否嘗試過使用'Instantiator'來創建狀態,並將它們填充到'states'中?如果有可能,我不知道,但現在只需很少的時間來嘗試。 – derM

+0

我試着用'Components'創建'states'數組。但我沒有成功。也許有人能夠做到這一點。 –

+0

爲什麼你需要在這裏使用狀態?你可以很容易地用關聯數組屬性來做到這一點。 – GrecKo

回答

3

代替使用States我會用一個普通的JavaScript關聯陣列。 您不能使用transitions,但您可以改爲使用Behavior。行爲不能做任何事情,但大部分時間都足夠了。

import QtQuick 2.7 
import QtQuick.Controls 2.0 
import QtQml 2.2 

ApplicationWindow { 
    id: mainWindow 
    visible: true 
    minimumWidth: 500 
    minimumHeight: 500 

    Row { 
     Rectangle { 
      id: rect 
      width: 100 
      height: 100 

      property var stateDescriptors: { 
       'state0': {color: 'green'}, 
       'state1': {color: 'red'}, 
       'state2': {color: 'blue'}, 
       'state3': {color: 'purple'}, 
       'state4': {color: 'orange'} 
      } 
      property string iconState: "state0" 

      Text { 
       anchors.fill: parent 
       text: parent.iconState 
      } 
      color: stateDescriptors[iconState].color 
      Behavior on iconState { 
       SequentialAnimation { 
        NumberAnimation { 
         target: rect; property: "scale" 
         to: 0; duration: 100 
        } 
        PropertyAction { } //actually change the iconState here, since the color is binded to it, it will also change between the 2 scale animations 
        NumberAnimation { 
         target: rect; property: "scale" 
         to: 1; duration: 100 
        } 
       } 
      } 
     } 

     Button { 
      text: 'change state' 
      property int count: 0 
      onClicked: { 
       count = (count + 1) % Object.keys(rect.stateDescriptors).length 
       rect.iconState = 'state' + count 
      } 
     } 
    } 
} 
1

也許這可以幫助你:

import QtQuick 2.7 
import QtQuick.Controls 2.0 
import QtQml 2.2 

ApplicationWindow { 
    id: mainWindow 
    visible: true 
    minimumWidth: 500 
    minimumHeight: 500 

    Row { 
     Rectangle { 
      id: rect 
      width: 100 
      height: 100 

      Text { 
       anchors.fill: parent 
       text: parent.state 
      } 

      property var myStates: [] 
      states: myStates 

      onStateChanged: console.log(Object.keys(rect.states)) 
     } 

     Button { 
      text: 'add state' 
      onClicked: { 
       rect.myStates.push(statePrototype.createObject(rect, 
                  { 
                   name: 'state' + count, 
                   color: Qt.rgba(Math.random(count), 
                       Math.random(count), 
                       Math.random(count), 
                       Math.random(count)) 
                  })) 
       rect.myStatesChanged() 
       count++ 
      } 
     } 

     Button { 
      text: 'change state' 
      onClicked: { 
       rect.state = 'state' + (count1 % count) 
       count1++ 
      } 
     } 

    } 

    property int count: 0 
    property int count1: 0 
    Component { 
     id: statePrototype 
     State { 
      id: st 
      property color color 
      PropertyChanges { 
       target: rect 
       color: st.color 
      } 
     } 
    } 
} 

這似乎不是那麼容易可以State s添加到states直接。隨着額外的英里越過了自定義property var myStates它突然起作用。 別忘了告訴大家,那加點東西后myStatesChanged()

編輯再一次,與JS對象列表和一個實例化器。的方法是相同的

import QtQuick 2.7 
import QtQuick.Controls 2.0 
import QtQml 2.2 

ApplicationWindow { 
    id: mainWindow 
    visible: true 
    minimumWidth: 500 
    minimumHeight: 500 

    Row { 
     Rectangle { 
      id: rect 
      width: 100 
      height: 100 

      Text { 
       anchors.fill: parent 
       text: parent.state 
      } 



      property var myStates: [] 
      states: myStates 
      onStateChanged: console.log(Object.keys(rect.states)) 
     } 

     Button { 
      text: 'change state' 
      property int count: 0 
      onClicked: { 
       rect.state = 'state' + count % rect.myStates.length 
       count ++ 
      } 
     } 

     Button { 
      text: 'add states' 
      onClicked: { 
       stateDescriptors.push({ name: 'state' + stateDescriptors.length, color: Qt.rgba(Math.random(1), 
                             Math.random(2), 
                             Math.random(3), 
                             Math.random(4)) }) 
       stateDescriptorsChanged() 
      } 
     } 
    } 

    Instantiator { 
     model: stateDescriptors 
     delegate: State { 
      name: modelData.name 
      PropertyChanges { 
       target: rect 
       color: modelData.color 
      } 
      Component.onCompleted: { 
       console.log('created', modelData.name) 
       rect.myStates.push(this) 
       rect.myStatesChanged() 
      } 
      Component.onDestruction: { 
       console.log('destroy', modelData.name) 
       rect.myStates.pop() 
      } 
     } 
    } 

    property var stateDescriptors: [ 
     { 
      name: 'state0', 
      color: 'green' 
     }, 

     { 
      name: 'state1', 
      color: 'red' 
     }, 

     { 
      name: 'state2', 
      color: 'blue' 
     }, 

     { 
      name: 'state3', 
      color: 'purple' 
     }, 

     { 
      name: 'state4', 
      color: 'orange' 
     } 
    ] 
}