Qt QTreeView:仅允许放置在现有项目上
我有一个继承自 QTreeView 的自定义模型。我已启用拖放功能,当前可以将项目拖放到树上。但是,您当前可以拖放到现有项目上或项目之间。我想限制这一点,以便您只能放置到现有的项目上。
我已将 DragDropOverwriteMode 设置为 true (实际上这是 QTreeView 的默认设置)。然而,这并不能阻止您在项目之间放置 - 它只是意味着您也可以放置在现有项目上。
我知道我可以通过检查行和列是否有效来忽略 dropMimeData 中的“插入”滴(我正在重新实现)(滴到现有项目上的行和列设置为 -1,父级设置为当前项目)并且我正在做这个。然而,我不想得到这些滴。 IE。我希望这样您总是可以跳过上面的项目或下面的项目,而不是在项目之间。
有什么想法吗?
感谢您的任何建议, 贾尔斯
I've got a custom model inherited from QTreeView. I've enabled drag and drop and can currently drop an item onto the tree. However, you can currently drop onto either an existing item or between items. I would like to restrict this so that you can only drop onto existing items.
I've set DragDropOverwriteMode to true (actually this is the default for QTreeView). However, this doesn't stop you from dropping between items - it just means you can also drop onto existing items.
I know that I can ignore the "insert" drops in dropMimeData (which I am reimplementing), by checking whether row and column are valid (drops onto existing items have row and column set to -1 and parent set to the current item) and I am doing this. However, I would prefer not to get these drops. Ie. I would like it so that you are always dropping over either the item above or the item below, never between items.
Any ideas?
Thanks for any advice,
Giles
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要通过在自定义视图中重新实现
dragEnterEvent
方法来捕获拖动输入事件。 Qt 文档中的示例是:在您的情况下,您可能需要将事件中的 x 和 y 位置与最近项目或类似内容的 x 和 y 位置进行比较,并根据该信息拒绝或接受建议的操作。
来自 QAbstractItemModel::dropMimeData 文档:
我将其解释为,如果底层模型(例如您的模型)不支持该视图,则该视图应该拒绝该放置。
You'' need to catch the drag enter events by reimplementing the
dragEnterEvent
method in your custom view. The example from the Qt docs is:In your case, you would probably need to compare the x and y position in the event with the x and y position of the closest item or something similar and reject or accept the proposed action based on that information.
From the
QAbstractItemModel::dropMimeData
documentation:Which I have interpreted to mean that the view should reject the drop if it's not something that's supported by an underlying model, such as yours.
从 Qt 5.4 开始(我认为即使在 Qt 4.8 中也是如此),将
DragDropOverwriteMode
设置为true
将正确导致拖动可放置仅在现有项目上,并防止出现“上方/下方项目”放置目标。另外,与问题所声称的不同,
QTreeView
的DragDropOverwriteMode
默认设置为false
(我没有检查,也许是较新的Qt版本),所以需要手动设置为true
。然而,能够计算出物品可以掉落的位置仍然很有用。例如,在 QTreeView 中,不能将拖动的东西放在项目的左边距,即下面的红色区域:
如果在无效的红色区域中放置了某些内容,
dropMimeData
将使用设置为NULL
的parent
参数进行调用。因此,提前忽略
dragMoveEvent
以向用户显示“你不能放在此处”光标以便他们知道会很有用他们不能掉在那里。 Qt 没有实现在拖动时更改无效区域上的鼠标光标(从 Qt 5.4 开始),但我们可以这样做:上面的代码包含一小部分
visualRect….adjusted(-1, -1, 1, 1)
是从QAbstractItemViewPrivate::position
来源窃取的。实际上,当 QAbstractItemViewPrivate::position 为 false 时,该函数的源也可用于计算项目的覆盖/插入/无效区域。As of Qt 5.4 (and I assume this was true even in Qt 4.8), setting
DragDropOverwriteMode
totrue
will correctly cause the drags to be droppable only on existing items and prevents the "above/below items" drop targets from appearing.Also, unlike what the question claims,
DragDropOverwriteMode
is set tofalse
by default forQTreeView
(I didn't check, maybe it's newer Qt versions), so it needs to be set totrue
manually.However it is still useful to be able to calculate on what positions the item can be dropped. For example in QTreeView, one cannot drop a dragged thing on the left margin of the items, i.e the red area below:
If something is dropped in the invalid red area,
dropMimeData
will be called with aparent
argument set toNULL
. So it would be useful toignore
thedragMoveEvent
in advance to show a 'you can't drop here' cursor to the user so they know they can't drop there. Qt doesn't implement changing the mouse cursor on invalid areas while dragging (as of Qt 5.4), but we can do it like this:The above code contains a little part
visualRect….adjusted(-1, -1, 1, 1)
which was stolen fromQAbstractItemViewPrivate::position
sources. Actually the sources of this function can be used to calculate the overwrite/insert/invalid areas for the item whenQAbstractItemViewPrivate::position
isfalse
too.我想建议一个基于放置指示器当前位置的解决方案(
QAbstractItemView::DropIndicatorPosition
)。实现起来非常简单,但不幸的是需要显示下降指示器。然而,在某些情况下这可能是可以接受的。I would like to suggest a solution based on the current position of the drop indicator (
QAbstractItemView::DropIndicatorPosition
). It's pretty simple to implement, but unfortunately requires the drop indicator to be shown. However, this might be acceptable in some cases.