在我的应用中,我使用QTreeView进行内部拖放操作。使用本教程,我可以通过使用mime类型" application / vnd.text.list"将其编码为字符串列表来高兴地拖放一个叶子。
然后我想拖放一个有一些孩子的树节点,并认为这样做的最佳途径是将指针编码到节点并迭代dropMimeData方法中的所有子节点。
我在mimeTypes()方法中声明了一个mime类型:
QStringList toResultModel::mimeTypes() const {
QStringList types;
types << "text/plain";
types << "application/vnd.mypointerlist.list";
return types;
}
尝试传递相同的字符串列表,但应用程序在dropMimeData()方法中崩溃。
似乎是mime类型&#34; application / vnd.text.list&#34;有一些我无法找到的隐藏意义。
我找到了这个源代码:http://fossies.org/linux/tora/src/toresultmodel.cpp,其中作者设置了自定义编码类型&#34; application / vnd.tomodel.list&#34;并且还使用&#34; application / vnd.int.list&#34;。
使用编码类型有哪些规则? 内置类型字符串定义在哪里? 我应该使用哪种类型将指针传递给树节点?
答案 0 :(得分:0)
四年后...
根据您提供的信息,如果方法崩溃,则与拖放无关,尤其是在代码中需要查找一些错误。也就是说,让我澄清一下Qt中的D&D,并回答有关MIME类型的问题。尽管您确实已经解决了四年前的问题,但对于今天的其他用户来说可能很有用。
您可以为应用程序定义自己的类型,也可以重用现有的类型。如何选择?
您可以使用现有的MIME类型,例如文本/纯文本吗?
请考虑您的应用程序是从另一个应用程序启动的D&D操作的目标。您可以接受现有的MIME类型并从中检索数据吗?
请考虑另一个应用程序是从您的应用程序内部启动的D&D操作的目标。此应用程序可以处理现有的MIME类型吗?
如果对所有问题的回答均为“否”,那么您可能必须使用自己的特定MIME类型。
格式名称本身并不重要
约束是它必须是唯一的,以便您不能从另一个应用程序接收格式错误的MIME数据,并且其他应用程序可以将MIME类型标识为无法处理的MIME类型,并忽略它。
确切的MIME类型名称无关紧要,因为您将在数据模型中提供编码器和解码器(例如,参见this introduction to view/model for Qt),以及有关使用的MIME类型的其他信息。
在QAbstractItemModel::mimeTypes
中,仅列出您可以处理的MIME类型。如果您不打算接受其他应用程序的MIME数据或从其他应用程序发送MIME数据,则无需允许超出特定的MIME类型。
当应用程序是D&D操作的源时,请对QAbstractItemModel::mimeData(indexes)
中的MIME数据进行编码(序列化)。即使有多个索引要拖动,序列化的结果也必须是字节数组。内部格式是您的。包括解码(反序列化)MIME数据所需的任何信息。请注意,您必须提供QAbstractItemModel::mimeTypes
中列出的每种MIME类型的编码数据(请参见上一点)。
将D&D数据拖到应用程序UI上时,将调用QAbstractItemModel::canDropMimeData(self, mime_data, action, row, column, parent)
以确定此位置是否有效。您可以在此处确定是否应在该位置允许放置。特别是,您可以测试所提供的MIME数据的内容,并使用mime_data.hasFormat(mime_type)
检查是否在要下垂的数据中找到所需的格式。返回false
将防止在此位置掉落,并且将向用户提供“此处不允许”指示(这不会取消D&D操作本身,用户可以继续将鼠标移至其他位置)。 / p>
实际删除数据时,将调用QAbstractItemModel::dropMimeData(mime_data, action, row, column, parent)
。获取使用QMimeData::hasFormat(mime_type)
使用的MIME数据格式。如果找不到所需的MIME类型,请忽略放置操作,因为无法解码提供的数据(D&D是从另一个应用程序启动的)。如前所述,该操作不应在删除数据之前发生,应用程序已调用QAbstractItemModel::canDropMimeData
。如果一切正常,请解码MIME数据,然后使用接收到的数据更新模型。
另一方面,您的树叶数据可能适合作为text/plain
MIME数据中编码的路径和名称,因此也许您也可以使用此类型。但是,由于其他应用程序可以生成不包含叶子描述的text/plain
数据,因此,在这种情况下,您需要具有识别无关数据并忽略它们的方法。很明显,与使用特定的MIME类型相比,这种方法需要更多的代码来验证drop操作的有效性。但是,这允许与其他应用程序进行交互,并且确实与从Excel(例如,单元格内容)或Firefox(例如,富文本或图像)之类的知名应用程序中拖动有关,否则我们无法使用D&D重用这些应用程序中的信息
您是否需要使用vnd
前缀?
vnd
表示“特定于供应商”。此前缀用于区分供应商创建的MIME类型和IANA授权创建的MIME类型。来自RFC 6838:
供应商树注册将通过前一个方面进行区分 “ vnd。”然后,由注册人酌情决定, 来自知名制作人的媒体子类型名称(例如, “ vnd.mudpie”)或由IANA批准的生产者的名称 名称后跟媒体类型或产品名称(例如, vnd.bigcompany.funnypictures)。
因此,在您的拖放教程中,application/vnd.text.list
是特定的,据说是某些供应商出于自己的目的而创建的。与application/vnd.mypointerlist.list
相反,text/plain
是IANA在RFC 2046中定义的标准MIME类型。这定义了人类可读的文本:
纯文本不提供或不允许使用格式命令,字体 属性规范,处理说明,解释 指令或内容标记。纯文本仅被视为 线性字符序列,可能被换行符打断 或分页符。纯文本可能允许堆叠多个 文字在同一位置。脚本中的纯文本 如阿拉伯语和希伯来语,也可能包括允许 具有相反书写方向的文本段的任意混合。
对于您的类型,出于一致性考虑,您可能希望使用vnd
,后跟特定于您的应用程序的子类型。但是可以看出,实际名称并不重要,只要您知道使用的是哪个名称,并且不与D&D链中的其他应用程序交互即可。