QMimeData 中的 Python 对象
我正在基于我的自定义模型实现拖放 QTreeView。一切正常,我的树显示数据,启用了拖放,现在最后一步就在我面前 - 放置和传输拖动的数据。为此,我需要在模型中实现 mimeTypes、mimeData 和 dropMimeData 方法。现在我的问题是:是否有任何简单的标准方法如何通过 QMimeData 传递任意 Python 对象?我只是在 QTreeView 中进行内部移动,它显示我的 Python 类 Person 的层次结构。我想重新排序它们。不能在应用程序之外进行拖放,甚至不能超出控制范围。我只找到了一个教程:链接文本。但这是唯一的方法吗?如果不将 Python 对象编码为 ByteArray,就无法完成此操作。我需要为我唯一的一类人提供非常简单的解决方案。谢谢。
I'm implementing drag and drop QTreeView based on my custom model. All works fine, my tree displays data, drag and drop is enabled and now the last step lies ahead of me - to drop and trasfer dragged data. To do this I need to implement mimeTypes, mimeData and dropMimeData methods in my model. And now my question: Is there any easy standard way how to pass an arbitrary Python object through QMimeData? I'm doing just an internal move within QTreeView which displays hierarchy of my Python classes Person. And I want to reorder them. No drag and drop outside the application, not even outside of control. I have found only single one tutorial: link text. But is it the only way? Cannot it be done without encoding the Python object into ByteArray. I need really simple solution for my only one class Person. Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不要尝试通过重新设置底层 python 对象的父级来实现拖放。如果阻力来自流程外部,则此方法将不起作用;它也不适用于复制操作(您的节点对象可能不能存在于树中的多个位置)。
将拖放“移动”视为三个操作:
mineData() 和 dropMimeData() 是您提供的序列化和反序列化操作。 Python 提供了一些简单的方法来实现它们——查看 pickle 模块的文档。如果你幸运的话,pickle.dumps() 和 pickle.loads() 将为你开箱即用。
编辑:我不知道如何在评论中粘贴代码,所以这是我的评论所指的解决方案。这是安全的,因为如果您碰巧违反了规则,它将通过抛出 KeyError 来失败,而不是导致崩溃。
Do not try to implement drag and drop by reparenting the underlying python object. This won't work if the drag comes from outside your process; nor will it work for a copy operation (your node objects probably cannot exist in multiple places in the tree).
Think of a drag and drop "move" as three operations:
mineData() and dropMimeData() are the serialize and deserialize operations that you provide. Python provides some easy ways to implement them -- check the documentation for the pickle module. If you're lucky, pickle.dumps() and pickle.loads() will work out-of-the-box for you.
Edit: I couldn't figure out how to paste code in comments, so here's the solution my comment refers to. This is safe, in the sense that it will fail by throwing a KeyError instead of causing crashes if you happen to break your rules.
好吧,我想我有一个可能的解决方案给你。
请记住,我在这个领域是一个完全的新手,所以不能保证他的a)有效b)是一个不错的解决方案c)不会让“真正的”程序员扔掉他们的午餐。
我所做的是将特定项目的整个祖先树转换为行列对的文本列表。 (即列出拖动项目的行和列,其父级的行和列,其父级的父级的行和列等......直到我们到达无效索引 - 即根)
这看起来像这样(此示例显示拖动的项目有四层深):
稍后,在 dropMimeData 函数中,我反转列表(以便它从根读回被拖动的项目)并一次构建一个索引,直到我回到最初拖动的项目。
以下是使这一切正常工作的代码片段。再次强调,我不能保证这是一个好主意,只是它看起来可行并且不需要您将 python 对象序列化为 ByteArray。
希望这有帮助。
Ok, I think I have a possible solution for you.
Keep in mind that I am a complete neophyte in this area so no warranties that his a) works b) is a decent solution c) won't make a "real" programmer toss their lunch.
What I did was convert the entire ancestor tree of a particular item into a text list of row column pairs. (i.e. list the row and column of the dragged item, the row and column of its parent, the row and column of its parent's parent, etc... till we get to an invalid index - i.e. the root)
This looks something like this (this example shows that the dragged item is four levels deep):
Later, in the dropMimeData function, I reverse the list (so that it reads from the root back down to the item being dragged) and build the indexes one at a time till I get back to the originally dragged item.
Here are the snippets of code that make that all work. Again, I can't warrantee that this is a good idea, just that it appears to work and does not require that you serialize your python objects into a ByteArray.
Hope this helps.