2012-08-31 36 views
5

Tôi đang theo cách tiếp cận được đưa ra trên http://qt-project.org/wiki/Drag_and_Drop_within_a_GridView.QML: GridView với các ô có thể di chuyển (kéo và thả)

Tôi có chương trình được trình bày. Kéo và thả đang hoạt động, nhưng sau khi thả, tôi nhận được không gian trống trong lưới của tôi. Làm thế nào tôi có thể cải thiện điều này?

Hơn nữa, tôi cũng nhận thấy rằng hàm indexAt() trong dòng 46 không hoạt động chính xác trong quá trình kéo. Vì vậy, tôi đã phải thêm tính toán rõ ràng của gridArea.index.

(CHỈNH SỬA) Có vẻ như không gian trống xuất hiện vì sau khi thả phần tử, nó được trả về vị trí ban đầu của nó (nó nằm bên dưới phần tử nhìn thấy được). GridView không được cập nhật và kết thúc ở trạng thái bất thường.

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

Trả lời

4

Ở đây, tôi cung cấp mã làm việc. Tôi đã thêm hiearchy bổ sung và đặt Rectangle vào Item. Hơn nữa, tôi phải sửa lại hình chữ nhật. Có nhiều giải pháp tương tự có sẵn, ví dụ: here.

Trong giải pháp đã cho, không có vấn đề với hàm indexAt() và do đó tính toán rõ ràng của gridArea.index là không cần thiết nữa.

Tôi sẽ đánh giá cao bất kỳ nhận xét nào về giải pháp này và tại sao những thay đổi này lại quan trọng như vậy. Tôi vẫn nghĩ rằng giải pháp ban đầu là trực quan và tôi không hiểu tại sao nó là không hoạt động.

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

Đây là câu trả lời khác bằng cách sử dụng thuộc tính kéo của MouseArea. Kỳ lạ của nó, nhưng giải pháp này có vấn đề với hàm indexAt(). Hơn nữa, có vẻ như không thể thêm hiệu ứng chuyển động chậm đẹp bằng cách sử dụng Hành vi trên x và y.

Bất kỳ nhận xét nào về giải pháp này cũng rất được hoan nghênh.

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) 
      } 
     } 
    } 
} 
Các vấn đề liên quan