我正在使用 PyQt6。 我想要一个带有可重新排序元素的 QTreeview。 但元素只能在比原来更深的同一层次结构中移动,就像在这张图片中一样,项目“A1”只能在文件夹“AAA”中重新排序
正如我所想,我可以通过
dragMoveEvent
实现,当光标显示“放入”工具提示时,我可以取消操作 - 但我没有找到相应的值来获取光标。
有人有同样的问题吗
这是代码:
class TreeViewWithReorder(QTreeView):
def __init__(self):
super().__init__()
self.setWindowTitle("Tree View with Reorderable Functionality")
self.resize(600, 400)
# Create a QStandardItemModel
self.model = QStandardItemModel()
# Create a root item
root_item = QStandardItem('AAA')
root_item_2 = QStandardItem('BBB')
# Create child items
technician1 = QStandardItem('A1')
technician2 = QStandardItem('A2')
technician3 = QStandardItem('A3')
technician4 = QStandardItem('B1')
technician5 = QStandardItem('B2')
# Add child items to the root items
root_item.appendRow(technician1)
root_item.appendRow(technician2)
root_item.appendRow(technician3)
root_item_2.appendRow(technician4)
root_item_2.appendRow(technician5)
# Set the model's root items
self.model.appendRow(root_item)
self.model.appendRow(root_item_2)
self.setModel(self.model)
self.setDragEnabled(True)
self.setAcceptDrops(True)
self.setDragDropMode(QTreeView.DragDropMode.InternalMove)
def dragMoveEvent(self, event):
super().dragMoveEvent(event)
您需要检查放置事件的可能目标是否与拖动的项目是同一个父级。
一种可能性如下:
def dragMoveEvent(self, event):
if event.source() != self:
event.ignore()
return
super().dragMoveEvent(event)
index = self.selectedIndexes()[0]
target = self.indexAt(event.pos())
if index.parent() == target or not event.isAccepted():
return
elif (
target.parent() != index.parent()
or self.dropIndicatorPosition() == self.DropIndicatorPosition.OnItem
):
event.ignore()
程序如下:
请注意,您应始终确保项目具有正确的拖/放标志。例如,根项目不应该是可拖动的,并且子项目可能不应该允许放在它们上面,否则它们也会成为父项目。
在您的情况下,对于基本的单层结构,您可以在
__init__
中执行以下操作:
for pr in range(self.model.rowCount()):
parent = self.model.item(pr)
parent.setFlags(parent.flags() & ~Qt.ItemFlag.ItemIsDragEnabled)
for cr in range(parent.rowCount()):
child = parent.child(cr)
child.setFlags(child.flags() & ~Qt.ItemFlag.ItemIsDropEnabled)
如果您的结构有多于一层,那么您最终应该仅针对 can 有子项的项目更改上述标志,因此您还需要在上面的
dragMoveEvent()
中进行检查。