2012-08-31 8 views
5

http://qt-project.org/wiki/Drag_and_Drop_within_a_GridViewに記載のアプローチに従っています。QML:移動可能なセルを持つGridView(ドラッグアンドドロップ)

私は提示されたプログラムを持っています。ドラッグアンドドロップは機能していますが、ドロップ後に私はグリッドに空きスペース を取得します。これをどのように改善できますか?

さらに、私は、行46の関数indexAt()がドラッグ操作中に正しく機能していないことにも気付きました。したがって、gridArea.indexの明示的な計算を追加しなければなりませんでした。

(編集済み)要素をドロップした後、元の位置に戻される(それは可視要素の下にあるため)空の領域が表示されるようです。 GridViewは更新されず、不規則な状態で終了します。

import QtQuick 1.1 

GridView { 
    id: mainGrid 
    cellWidth: 165; cellHeight: 95 
    width: 5*cellWidth; height: 4*cellHeight 
    model: myModel 
    delegate: myButton 

    ListModel { 
     id: myModel 
     function createModel() { 
      for (var i=1; i<=20; i++) { 
       myModel.append({"display": i, "uid": i}) 
      } 
     } 
     Component.onCompleted: {createModel()} 
    } 

    Component { 
     id: myButton 
     Rectangle { 
      id: item 
      width: mainGrid.cellWidth-5; height: mainGrid.cellHeight-5; 
      border.width: 1 
      property int uid: (index >= 0) ? myModel.get(index).uid : -1 
      Text { 
       anchors.centerIn: parent 
       text: display 
       font.pixelSize: 48 
      } 
      states: [ 
       State { 
        name: "active"; when: gridArea.activeId == item.uid 
        PropertyChanges {target: item; x: gridArea.mouseX-80; y: gridArea.mouseY-45; z: 10; smooth: false} 
       } 
      ] 
     } 
    } 

    MouseArea { 
     id: gridArea 
     anchors.fill: parent 
     hoverEnabled: true 
     preventStealing : true 
     //property int index: mainGrid.indexAt(mouseX, mouseY) //WHY IS THIS NOT WORKING RELIABLE? 
     property int mX: (mouseX < 0) ? 0 : ((mouseX < mainGrid.width - mainGrid.cellWidth) ? mouseX : mainGrid.width - mainGrid.cellWidth) 
     property int mY: (mouseY < 0) ? 0 : ((mouseY < mainGrid.height - mainGrid.cellHeight) ? mouseY : mainGrid.height - mainGrid.cellHeight) 
     property int index: parseInt(mX/mainGrid.cellWidth) + 5*parseInt(mY/mainGrid.cellHeight) //item underneath cursor 
     property int activeId: -1 //uid of active item 
     property int activeIndex //current position of active item 
     onPressAndHold: { 
      activeId = mainGrid.model.get(activeIndex=index).uid 
     } 
     onReleased: { 
      activeId = -1 
     } 
     onPositionChanged: { 
      if (activeId != -1 && index != -1 && index != activeIndex) { 
       mainGrid.model.move(activeIndex, activeIndex = index, 1) 
      } 
     } 
    } 
} 

答えて

4

ここでは、作業コードを示します。私は追加のhiearchyを追加し、RectangleをItemに入れました。さらに、私はRectangleを再現しなければならなかった。同じような解決策が多数あります。 here

関数では、indexAt()関数に問題はないため、gridArea.indexの明示的な計算はもう必要ありません。

このソリューションのコメントと、これらの変更が重要な理由をお分かりいただけると思います。 私はまだ元のソリューションは直感的だと思うし、なぜそれが が機能しないのかわかりません。

import QtQuick 1.1 

GridView { 
    id: mainGrid 
    cellWidth: 165; cellHeight: 95 
    width: 5*cellWidth; height: 4*cellHeight 
    model: myModel 
    delegate: myButton 

    ListModel { 
     id: myModel 
     function createModel() { 
      for (var i=1; i<=20; i++) { 
       myModel.append({"display": i, "uid": i}) 
      } 
     } 
     Component.onCompleted: {createModel()} 
    } 

    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 
       property int uid: (index >= 0) ? myModel.get(index).uid : -1 
       Text { 
        anchors.centerIn: parent 
        text: display 
        font.pixelSize: 48 
       } 
       states: [ 
        State { 
         name: "active"; when: gridArea.activeId == box.uid 
         PropertyChanges {target: box; x: gridArea.mouseX-80; y: gridArea.mouseY-45; z: 10} 
        } 
       ] 
      } 
     } 
    } 

    MouseArea { 
     id: gridArea 
     anchors.fill: parent 
     hoverEnabled: true 
     preventStealing : true 
     property int index: mainGrid.indexAt(mouseX, mouseY) //item underneath cursor 
     property int activeId: -1 //uid of active item 
     property int activeIndex //current position of active item 

     onPressAndHold: { 
      activeId = mainGrid.model.get(activeIndex=index).uid 
     } 
     onReleased: { 
      activeId = -1 
     } 
     onPositionChanged: { 
      if (activeId != -1 && index != -1 && index != activeIndex) { 
       mainGrid.model.move(activeIndex, activeIndex = index, 1) 
      } 
     } 
    } 
} 
1

これは、MouseAreaのdragプロパティを使用した別の回答です。その奇妙ですが、この解決策は関数indexAt()に問題があります。さらに、xとyのBehaviorを使って素晴らしいスローモーションエフェクトを追加することはできないようです。

このソリューションに関するご意見もあります。

import QtQuick 1.1 

GridView { 
    id: mainGrid 
    cellWidth: 165; cellHeight: 95 
    width: 5*cellWidth; height: 4*cellHeight 
    model: myModel 
    delegate: myButton 

    ListModel { 
     id: myModel 
     function createModel() { 
      for (var i=1; i<=20; i++) { 
       myModel.append({"display": i}) 
      } 
     } 
     Component.onCompleted: {createModel()} 
    } 

    Component { 
     id: myButton 
     Rectangle { 
      id: item 
      z: 1 
      width: mainGrid.cellWidth-5; height: mainGrid.cellHeight-5; 
      border.width: 1 
      Text { 
       anchors.centerIn: parent 
       text: display 
       font.pixelSize: 48 
      } 
     } 
    } 

    MouseArea { 
     id: gridArea 
     anchors.fill: parent 
     hoverEnabled: true 
     drag.axis: Drag.XandYAxis 
     //property int index: mainGrid.indexAt(mouseX,mouseY) //NOT WORKING RELIABLE! 
     property int mX: (mouseX < 0) ? 0 : ((mouseX < mainGrid.width - mainGrid.cellWidth) ? mouseX : mainGrid.width - mainGrid.cellWidth) 
     property int mY: (mouseY < 0) ? 0 : ((mouseY < mainGrid.height - mainGrid.cellHeight) ? mouseY : mainGrid.height - mainGrid.cellHeight) 
     property int index: parseInt(mX/mainGrid.cellWidth) + 5*parseInt(mY/mainGrid.cellHeight) //item underneath cursor 
     property int activeIndex 

     onPressAndHold: { 
      currentIndex = index 
      currentItem.z = 10 
      gridArea.drag.target = currentItem 
      activeIndex = index 
     } 
     onReleased: { 
      currentItem.x = mainGrid.cellWidth * (index % 5) 
      currentItem.y = mainGrid.cellHeight * parseInt(index/5) 
      currentItem.z = 1 
      currentIndex = -1 
      gridArea.drag.target = null 
     } 
     onPositionChanged: { 
      if (drag.active && index !== -1 && index !== activeIndex) { 
       mainGrid.model.move(activeIndex, activeIndex = index, 1) 
      } 
     } 
    } 
} 
関連する問題