【发布时间】:2017-11-22 20:39:38
【问题描述】:
我有一个简单的文件处理小部件,它可以从剪贴板复制/剪切/粘贴选定的文件。我希望能够在此小部件和 Windows 资源管理器(可能是其他文件管理器,例如 Total Commander 或 Free Commander)之间使用这些命令交换文件。我已经发现我可以使用QMimeData::setUrls() 将文件名作为QList<QUrl> 存储到剪贴板并以类似方式恢复它们。这样我就可以在我的小部件和上述文件管理器之间复制和粘贴,因为它们似乎使用相同的格式来存储文件名。但我不知道如何将项目剪切到剪贴板(即粘贴文件后删除)。我假设接收者(粘贴数据的应用程序)负责删除剪切文件。在这种情况下,它必须以某种方式在剪贴板数据中编码,文件已被剪切而不是复制,接收应用程序可以检索此信息。这是怎么做到的?或者还有其他方法吗?我知道这是可能的,因为这可以在 Windows Explorer 和 Free Commander 之间完美运行。 IE。当您在 Window Explorer 中剪切文件并将其粘贴到 Free Commander 时,原始文件会被删除,反之亦然。
更新:
我发现还有另一部分 MIME 数据"Preferred DropEffect" 的值可以是5(复制)或2(剪切)。当我将QByteArray设置为4个字节,对应一个整数值5或2时,我可以区分Windows资源管理器是启动剪切还是复制。如果它被剪切,那么我可以移动文件而不是复制。它运作良好。不幸的是,这仍然只有从 Windows Explorer 到 Qt 应用程序的一种方式。我仍然没有找到为什么相反的方向不起作用。还有一些其他的 MIME 数据对我来说很难解码。也许有钥匙。
更新 2: 重现行为的最小代码在这里。确保程序中硬编码的文件存在。尝试运行程序,关闭窗口后打开打开 Windows 资源管理器,转到可以写入的任意文件夹,然后按 Ctrl+V... 然后文件的副本应出现在该目录中,但不会从源目录中删除.下面的程序使用常量 2 表示剪切而不是复制,这意味着原始文件应该消失。
#include <QApplication>
#include <QClipboard>
#include <QDataStream>
#include <QMimeData>
#include <QUrl>
#include <QWidget>
int main(int argc, char *argv[])
{
QApplication application(argc, argv);
auto mimeData = new QMimeData;
// store the URL to files which I want to cut
QList<QUrl> urls;
urls.append(QUrl::fromLocalFile("C:/mypath/myfile.txt")); // use your path or make sure this file exist
mimeData->setUrls(urls);
// store drop effect indicating whether I want to cut or copy
int dropEffect = 2; // 2 for cut and 5 for copy
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
stream << dropEffect;
mimeData->setData("Preferred DropEffect", data);
QApplication::clipboard()->setMimeData(mimeData);
QWidget window;
window.show();
return application.exec();
}
另请参阅How to programmatically cut/copy/get files to/from the Windows clipboard in a system standard compliant form? 和 https://msdn.microsoft.com/en-us/library/windows/desktop/bb776904(v=vs.85).aspx#delete_on_paste
【问题讨论】:
-
为什么是减分?这个问题有什么问题?
-
我更新了问题以包含一些最少的代码。