2

カスタム QListView があります。

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from Diagnostics import Trace2 #writes to log file
import traceback

class ListOrderView(QListView):

    itemMoved = pyqtSignal(int, int, QStandardItem) # Old index, new index, item 

    def __init__(self, parent=None):
        try:
            super(ListOrderView, self).__init__(parent)

            self.setAcceptDrops(True)
            self.setDragEnabled(True)
            self.setDragDropMode(QAbstractItemView.InternalMove)
            self.setDefaultDropAction(Qt.MoveAction)

            self.setEditTriggers(QAbstractItemView.NoEditTriggers)
            self.setSelectionBehavior(QAbstractItemView.SelectRows)
            self.setSelectionMode(QAbstractItemView.SingleSelection)

            self.dragItem = None
            self.dragRow = None

            self.indexesMoved.connect(self.onIndexesMoved)
            #self.installEventFilter(self)
        except:
            Trace2.WriteLine(str(traceback.format_exc()))

    def onIndexesMoved(self, indexes):
        Trace2.WriteLine("indexes were moved")

    def dropEvent(self, event): 
        try:
            super(ListOrderView, self).dropEvent(event) 

            self.selectionModel().setCurrentIndex(self.model().indexFromItem(self.dragItem), QItemSelectionModel.SelectCurrent)
            Trace2.WriteLine("[LISTVIEW] item dropped")
            Trace2.WriteLine("[LISTVIEW] current index is %d" %self.selectionModel().currentIndex().row())
            Trace2.WriteLine("[LISTVIEW] current selection is %d" %self.selectionModel().selection().indexes()[0].row())

            self.itemMoved.emit(self.dragRow, self.row(self.dragItem), self.dragItem)
            self.dragItem = None
        except:
            Trace2.WriteLine(str(traceback.format_exc()))

    def startDrag(self, supportedActions): 
        try:
            self.dragItem = self.currentItem() 
            self.dragRow = self.row(self.dragItem) 
            super(ListOrderView, self).startDrag(Qt.MoveAction)
        except:
            Trace2.WriteLine(str(traceback.format_exc()))

    def currentItem(self):
        index = self.currentIndex()
        item = self.model().itemFromIndex(index)
        #Trace2.WriteLine("[LISTVIEW] currentItem = %s" % item.data(Qt.DisplayRole).toString())
        return item

    def row(self, item):
        #index = self.model().indexFromItem(item)
        index = self.selectedIndexes()[0]
        row = index.row()

        #Trace2.WriteLine("[LISTVIEW] row = %d" %row)
        return row

そして、ドラッグ アンド ドロップ操作の後にアイテムがどこにドロップされたかを本当に知る必要があるので、他のものを適切に更新できます (私のデザインではなく、そのために設計されていない大きなアプリにドラッグ アンド ドロップを入れようとしています)。選択モデルの現在のインデックスと選択は、ドロップされたアイテムに追従しません。それらは効果的に新しいアイテムを選択し、物事を台無しにします。ドロップしたアイテムと一緒に動かす方法はありますか? シグナル indexMoved は、私が望むものとまったく同じように見えますが、決して発火しません。私はそれを間違って使用していますか?別の/より良い方法はありますか?

4

1 に答える 1

3

最終的に移動を処理するため、実際にモデルに何かがドロップされた場所を伝える必要があると思います。

class Model(QStandardItemModel):

    rowDropped = pyqtSignal(int)

    def dropMimeData(self, *args):
        success =  super(Model, self).dropMimeData(*args)
        if success:
            self.rowDropped.emit(args[2])
        return success

これにより、ドロップが発生した行番号がモデルから出力されます。ビューは、独自のイベントからどのアイテムがドラッグ アンド ドロップされたかを既に認識しています。

オブジェクトを追跡し、ドロップが完了した後に再度クエリを実行するという点で、他の方法があると確信しています。

于 2012-10-11T19:51:30.850 に答える