在我的应用程序中,我正在显示音频文件列表,用户可以拖动外部文件以将其添加到列表中。如果我的应用程序不支持列表中的文件,我希望能够拒绝拖动。
问题是,当我在自己的drag.accepted = false;
的onEntered
中调用DropArea
时,它对所有其他事件完全无响应。
这是一些显示此问题的示例代码。如果将MP3拖到窗口中,则会看到它起作用。然后,如果您拖动任何其他文件,它将无法正常工作。但是然后将MP3
文件拖回也将不起作用。
import QtQuick 2.1
import QtQuick.Window 2.0
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
DropArea {
anchors.fill: parent
onEntered: {
console.log("[Droparea] entered");
// Ensure at least one file is supported before accepted the drag
var validFile = false;
for(var i = 0; i < drag.urls.length; i++) {
if(validateFileExtension(drag.urls[i])) {
validFile = true;
break;
}
}
if(!validFile) {
console.log("No valid files, refusing drag event");
drag.accepted = false;
return false;
}
}
onExited: {
console.log("[Droparea] entered");
}
onDropped: {
console.log("[Droparea] dropped");
}
// Only MP3s
function validateFileExtension(filePath) {
var extension = filePath.split('.').pop();
var valid = false;
if(extension == "mp3") {
valid = true;
}
return valid;
}
}
Text {
id: textDrop
anchors.centerIn: parent
text: "Please drag element"
}
}
DropArea
中是否存在错误,或者我是否误解了某些内容?我知道我可以过滤onDropped中的文件,但是当在不接受文件的区域上拖动文件时,您会失去在OSX上获得的视觉反馈。 最佳答案
很长一段时间以来一直是known bug。补丁已提交,并且停滞了几个月后现在变成merged into 5.6 branch。
任何想要使用此功能的人都必须升级到Qt 5.6或MANULLY将可用的补丁程序集成到他/她的Qt版本中。 QQuickDropAreaPrivate
中包含的 DropArea
在发生containsDrag
时将 true
标志更新为dragEnterEvent
,并发出 entered
信号。当出现containsDrag
时,它将false
更新为dragLeaveEvent
,并发出 exited
信号。但是,当不接受拖动事件时,永远不会调用dragLeaveEvent
,从而使私有(private)对象处于困惑状态。因为dragEnterEvent
仍然是containsDrag
,所以每个后续的true
都将被丢弃,即,先前的拖动事件仍被认为是 Activity 的,并且entered
不再发出。
由于此问题与私有(private)API和公共(public)API的使用之间的交互有关,因此该问题不会影响使用 keys
进行的过滤。不幸的是,这种方法似乎不适合所提出的用例。
相当一部分的解决方法是将MouseArea
与DropArea
一起使用。当拒绝发生时,后者会禁用自身,而前者会在下一次丢弃时启用DropArea
。此解决方法涵盖了将错误的项目放入DropArea
内的常见情况,这对于最终用户而言是最常见和直观的。释放DropArea
之外的错误项会使该机制失效(直到下一个下降)。
这是代码:
import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Window 2.0
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
visible: true
MouseArea {
anchors.fill: parent
hoverEnabled: true
enabled: !drop.enabled
onContainsMouseChanged: drop.enabled = true
}
DropArea {
id: drop
anchors.fill: parent
onEntered: {
console.log("[Droparea] entered");
// Ensure at least one file is supported before accepted the drag
for(var i = 0; i < drag.urls.length; i++)
if(validateFileExtension(drag.urls[i]))
return
console.log("No valid files, refusing drag event")
drag.accept()
drop.enabled = false
}
onExited: console.log("[Droparea] exited")
onDropped: console.log("[Droparea] dropped")
// Only MP3s
function validateFileExtension(filePath) {
return filePath.split('.').pop() == "mp3"
}
}
Text {
id: textDrop
anchors.centerIn: parent
text: "Please drag element"
}
}
关于qt - 拒绝在DropArea中拖动的外部文件,而不会破坏DropArea,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22787242/