我用Qt 4.x写了一个用C++写的小文件传输应用程序...它登录到服务器,向用户显示服务器上可用文件的列表,并允许用户上载或下载文件。
这一切都很好;您甚至可以从桌面(或从打开的文件夹)拖入一个文件,当您将文件图标拖放到server-files-list-view中时,拖放的文件将上载到服务器。
现在我也有一个相反的请求……我的用户希望能够将文件从server-files-list-view拖到桌面上,或者拖到打开的文件夹窗口中,并将该文件下载到该位置。
这似乎是一个合理的请求,但我不知道如何实现它。当图标被放到桌面上或打开的文件夹窗口中时,Qt应用程序有没有办法找到与"drop event“发生位置对应的目录?理想情况下,这将是基于Qt的平台中立机制,但如果不存在,那么针对MacOS/X和Windows (XP或更高版本)的特定于平台的机制就足够了。
有什么想法吗?
发布于 2010-04-28 17:43:53
看看QMimeData
和它的文档,它有一个虚拟函数
virtual QVariant retrieveData ( const QString & mimetype, QVariant::Type type ) const
这意味着您是否要拖动到外部并相应地实现此函数
class DeferredMimeData : public QMimeData
{
DeferredMimeData(QString downloadFilename) : m_filename(downloadFilename)
virtual QVariant retrieveData (const QString & mimetype, QVariant::Type type) const
{
if (mimetype matches expected && type matches expected)
{
perform download with m_filename
}
}
}
delayed encoding示例说明了这一原则。
您可能还必须重写hasFormat
和formats
来提供适当的类型,application/octet-stream
可能是最能让您发挥作用的类型,您可能还需要阅读有关windows如何使用mime类型专门处理拖放的内容。
我不知道您将如何提供保存文件的文件名,但您可能必须进入windows端的东西。查看QWindowsMime
的源代码可能也会有所帮助。可能会有一个多步骤的过程,在这个过程中,您将获得文件名的text/uri-list
数据请求,然后是数据的application/octet-stream
请求。
希望这能有所帮助
发布于 2010-04-28 04:24:03
我认为你以错误的方式去做那件事。
你不关心丢到哪里去了,你只知道它是被丢下的。在DropEvent中,将文件下载到临时位置,然后将mime数据设置为所下载的数据。假设这可能会以硬盘驱动器的第二个副本结束,它将从一开始就是跨平台的。之后,您可以使用特定于平台的调用对其进行优化。
看看Dropsite example,看看其他来源的mime数据是如何工作的……
编辑:
如果你不写shell扩展(至少对于windows来说),双重复制方法看起来是标准的。Filezilla和7zip都是这样做的,它们返回一个带有临时位置的"text/uri-list“mime类型。通过这种方式,资源管理器将数据从临时位置复制到真实位置。你的应用程序也可以做同样的事情,创建一个没有数据的临时文件(或者只是文件名)。使用delayed encoding example在drop上创建数据。这整个操作看起来是非常特定于平台的。在Linux (运行KDE)上,我可以根据mime类型进行拖放。windows似乎没有那么灵活。
发布于 2010-04-28 06:37:11
只需实现the drag part即可。你不需要知道拖放发生在哪里,因为接收它的应用程序将处理它并决定将你的文件存储在哪里。
您创建了一个应用程序,不确定是哪种类型,但从我看到的here和here来看,可能是“QMimeData /octet-stream”,将您的文件作为QByteArray中的数据,或者"text/uri-list“,包含指向您文件的url。
您创建一个QDrag,并使用它的setMimeData()方法和exec() (不确定选择哪个QT::DropAction )。
下面是一个例子(disclamer :我是用颜色而不是文件):
void DraggedWidget::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
start_pos = event->pos();
}
void DraggedWidget::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
int distance = (event->pos() - start_pos).manhattanLength();
if (distance >= QApplication::startDragDistance())
{
/* Drag */
QMimeData *mime_data = new QMimeData;
mime_data->setData( ... );
QDrag *drag = new QDrag(this);
drag->setMimeData(mime_data);
drag->exec(Qt::CopyAction);
}
}
}
对不起,它是相当不完整的,我希望它有一点帮助。
https://stackoverflow.com/questions/2724252
复制相似问题