在我的应用程序中,我正在显示音频文件列表,用户可以拖动外部文件将其添加到列表中.如果我的应用程序不支持列表中的文件,我希望能够拒绝拖动.
问题是,当我打电话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"
}
}
Run Code Online (Sandbox Code Playgroud)
是否有错误DropArea或我误解了什么?我知道我可以过滤onDropped中的文件,但是当你在不接受它们的区域上拖动文件时,你会失去在OSX上获得的视觉反馈.
很长一段时间它一直是一个已知的bug.已经提交了一个补丁,经过几个月的停滞后现已合并到5.6分支中.
任何想要使用此功能的人必须升级到Qt 5.6或MANULLY将可用的补丁集成到他/她的Qt版本中.
QQuickDropAreaPrivate包含DropArea在内,将containsDrag标志更新true为dragEnterEvent发生时,发出entered信号.它更新containsDrag到false当dragLeaveEvent发生时,发射exited信号.但是,当不接受拖动事件时,dragLeaveEvent永远不会调用,从而使私有对象处于不存在状态.dragEnterEvent因为containsDrag仍然存在true,所以每个后续都被丢弃,即先前的拖动事件仍被认为是活动的并且entered不再发出.
由于该问题与私有API和公共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"
}
}
Run Code Online (Sandbox Code Playgroud)
Blu*_*gma -1
你从来没有把accepteed = true
只需在将 valid 设置为有效后添加 Drag.accepted = true
for(var i = 0; i < drag.urls.length; i++) {
if(validateFileExtension(drag.urls[i])) {
validFile = true;
drag.accepted = true;
break;
}
}
Run Code Online (Sandbox Code Playgroud)