qt:QTreeView - 限制拖放只发生在一个特定的祖父母(祖先)内
问题描述:
我有一个QTreeView,我已经在其中实现拖放以允许重新排序项目。qt:QTreeView - 限制拖放只发生在一个特定的祖父母(祖先)内
给定树的下面的例子:
Food <--fixed
|--Vegetables <--fixed
| |--carrots <-- draggable/parentable
| |--lettuce <-- draggable/parentable
| | |--icebergLettuce <-- draggable but NOT parentable
|--Fruit <-- fixed
| |--apple <-- draggable/parentable
| |--orange <-- draggable/parentable
| |--bloodOrange <-- draggable/parentable
etc...
任何标记为可拖动可以被拖动。任何标记为可父母的项目可能会有一个可拖动的项目作为孩子。标记为固定的任何东西都是固定的。
我的问题是,我将如何去限制物品的丢弃以保留在特定的父级中?例如,我可以拖动'bloodOrange'使其成为'apple'或'orange'的孩子(甚至只是改变它在'Fruit'中的序位),但我不应该让它成为胡萝卜的孩子或生菜等
我已经设法正确编码除了限制放置操作,留在一个特定的父母的部分的标志。我只是不知道如何捕获当前拖动的QModelIndex(从中我可以确定父母,祖父母等)
谢谢!
这里是我的代码为旗帜的方法,如果它有帮助:注:我指的*儿童节点(即'食品'),下一级作为组(即'水果'),和最后两个级别(即生菜和冰山生菜)都是Params。
#---------------------------------------------------------------------------
def flags(self, index):
"""
Returns whether or not the current item is editable/selectable/etc.
"""
if not index.isValid():
return QtCore.Qt.ItemIsEnabled
#by default, you can't do anything
enabled = QtCore.Qt.NoItemFlags
selectable = QtCore.Qt.NoItemFlags
editable = QtCore.Qt.NoItemFlags
draggable = QtCore.Qt.NoItemFlags
droppable = QtCore.Qt.NoItemFlags
#get a pointer to the referenced object
item = index.internalPointer()
#only 'valid' cells may be manipulated ('valid' is defined by the obj)
if item.column_is_valid(index.column()):
#all valid cells are selectable and enabled
selectable = QtCore.Qt.ItemIsSelectable
enabled = QtCore.Qt.ItemIsEnabled
#column 0 cells may occasionally be dragged and dropped
if index.column() == 0:
#drag/drop is only possible if it is a param...
if item.get_obj_type() == 'param':
#...and then only child-less params may be dragged...
if item.get_child_count() == 0:
draggable = QtCore.Qt.ItemIsDragEnabled
#...and only params with a group as parent may be dropped on
if item.get_parent().get_obj_type() == "group":
droppable = QtCore.Qt.ItemIsDropEnabled
#all other valid columns > 0 may be edited (no drag or drop)
else:
editable = QtCore.Qt.ItemIsEditable
#return our flags.
return enabled | selectable| editable| draggable| droppable
答
如果你想拖动鼠标悬停在某些行时显示“不允许”图标,我相信你无法从模型做到这一点。您必须拦截View wiedget上的dragEnter/Move事件。
但是,dropMimeData()可以返回False以指示该拒绝被拒绝。
请注意(在我的Qt版本中)qdnd_win中存在一个错误,关于被模型拒绝的丢弃。这里是我基于某些源潜水的解决方法;这是对我的QTreeView则子类中定义的方法:通过“不可忽略的作品”
def dropEvent(self, evt):
QTreeView.dropEvent(self, evt)
if not evt.isAccepted():
# qdnd_win.cpp has weird behavior -- even if the event isn't accepted
# by target widget, it sets accept() to true, which causes the executed
# action to be reported as "move", which causes the view to remove the
# source rows even though the target widget didn't like the drop.
# Maybe it's better for the model to check drop-okay-ness during the
# drag rather than only on drop; but the check involves not-insignificant work.
evt.setDropAction(Qt.IgnoreAction)
(请注意,我真正的意思是:“我不希望打扰拦截事件” :-)
这是非常有帮助的感谢,我遇到了这个确切的问题。 – TrevorB 2014-03-12 16:23:50