如何修改 QListView 中的放置事件

问题描述

我有一个 QListView,可以通过将 dragDropMode 设置为 DragDrop 并将 defaultDropAction 设置为 MoveAction 来通过拖放重新排序项目。我如何拦截 drop 事件,以找出与列表的其余部分相关的尝试移动的位置,以便我可以在某些条件下取消此操作?例如。我想禁止将某些物品移到其他物品后面。

解决方法

您可以访问dropEvent 中涉及的索引和项目,并将DropAction 设置为Qt.IgnoreAction 以根据您的条件取消删除。由于您没有具体说明,因此在本演示中,我只创建了一个位于底部的项目。

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class List(QListView):

    def dropEvent(self,event):
        i = self.selectedIndexes()[0]
        j = self.indexAt(event.pos())

        # To access the items involved
        source = self.model().itemFromIndex(i)
        target = self.model().itemFromIndex(j)

        bottom = (self.model().rowCount() - 1,-1)
        if i.row() in bottom or j.row() in bottom:
            event.setDropAction(Qt.IgnoreAction)
        else:
            super().dropEvent(event)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = QWidget()
    lv = List()
    lv.setDragDropMode(QAbstractItemView.DragDrop)
    lv.setDefaultDropAction(Qt.MoveAction)
    
    model = QStandardItemModel(5,1)
    for i in range(4):
        item = QStandardItem(f'Item {i + 1}')
        item.setFlags(item.flags() & ~Qt.ItemIsDropEnabled)
        model.setItem(i,item)    
    item = QStandardItem('I stay at the bottom ._.')
    model.setItem(4,item)
    lv.setModel(model)
    
    vbox = QVBoxLayout(window)
    vbox.addWidget(lv)
    window.show()
    sys.exit(app.exec_())