如何在 QListView 中修改 drop 事件

Posted

技术标签:

【中文标题】如何在 QListView 中修改 drop 事件【英文标题】:How to modify drop event in QListView 【发布时间】:2021-04-02 21:32:23 【问题描述】:

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

【问题讨论】:

子类化并实现dropEvent,如果操作不太复杂,则使用事件过滤器。 【参考方案1】:

您可以访问dropEvent 中涉及的索引和项目,并将setDropAction 设置为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, 0, item)    
    item = QStandardItem('I stay at the bottom ._.')
    model.setItem(4, 0, item)
    lv.setModel(model)
    
    vbox = QVBoxLayout(window)
    vbox.addWidget(lv)
    window.show()
    sys.exit(app.exec_())

【讨论】:

谢谢,这很有帮助。你能详细说明~Qt.ItemIsDropEnabled的用法吗?我不明白为什么这是颠倒的?当我删除 tilda items1-4 时变为非活动状态(灰色且无法选择)。 @MJB 默认情况下启用 ItemIsDropEnabled 标志,在这种情况下,您可以将一个项目放入另一个项目,从而导致后者被删除/替换。所以& ~ItemIsDropEnabled 删除了那个标志和那个行为。如果您确实需要该功能,则删除整行,仅删除 ~ 将导致标志的按位 OR 无效。

以上是关于如何在 QListView 中修改 drop 事件的主要内容,如果未能解决你的问题,请参考以下文章

在 Qt 中找不到 Qlistview Selectionchanged 事件?

QListView 更新 - 不触发更新

PyQt5允许在编辑时选择QListView项

PyQt4 - 在 QListView 中的项目上按下 Enter 键

QListView 悬停事件?

带有自定义项目的 QListView => 鼠标事件被传播