类型:Python,C++ & Qt4,创建时间:Jan. 1, 2012, 8:52 p.m.
标题无“转载”即原创文章,版权所有。转载请注明来源:http://hgoldfish.com/blogs/article/54/。
我是EditPlus和FileZilla的用户。这两个软件都支持文件拖拽。我们可以从资源管理器中拖动一个文件到EditPlus的窗口,EditPlus就会自动打开这个文件。或者拖到FileZilla的远程窗口内,FileZilla就会自动将文件上传到服务器。我经常希望自己的软件也支持拖动的操作。
作为基本功能,大多数操作系统都各自定义了拖放所需的通信协议。Qt对此做了一个很好的封装。基本的流程是:当用户从其它应用程序拖动文件、文本、图像等到Qt程序时,Qt会自动产生一个DrapEnterEvent
,应用程序可以判断数据是不是可以处理的。如果能处理,就反馈给Qt,这样的话,用户就会看到一个接受拖放的标识。待用户放开鼠标时,Qt再产生一个DropEvent
。最后应用程序从事件中取出数据进行处理。
那么应用程序如何判断程序是否可以处理拖放的数据呢?很简单,数据中包含了MIME类型。MIME类型是一个用于标识二进制数据类型的Internet标准。很多朋友可能习惯通过文件的扩展名来判断数据类型,但是扩展名只有短短的几个字符,常常有歧义。通常,如果应用程序要处理文本,就判断MIME类型是不是"text/palin"
,如果要处理JPEG图像,就判断MIME类型是不是"image/jpeg"
,等等。同一段数据通常包含多种MIME类型,比如拖动富文本时,数据中可能包含纯文本、HTML文本、图像。应用程序可以选择处理所支持的数据格式。
在Windows平台下,拖放首先的数据多种多样,有很多没有标准的MIME类型。这时Qt自动转换成形如application/x-qt-windows-mime;value="FileNameW"
这样的MIME类型。实际上,这就是拖放文件时文件名的MIME类型。为了更跨平台一点,文件名也可以表示为"text/uri-list"
类型。
为了让一个控件能够接受被拖动的文件,我们需要重新实现QWidget的几个方法。这是简单的PyQt代码,只适用于windows平台,稍微修改为"text/uri-list"
就可以跨平台:
specialMimeType="application/x-qt-windows-mime;value=\"FileNameW\"" class WrtierWindow(QMainWindows): def __init__(self): QMainWindow.__init__(self, parent, flags) self.setAcceptDrops(True) def dragEnterEvent(self, event): if event.mimeData().hasFormat(specialMimeType): event.acceptProposedAction() def dropEvent(self, event): if not event.mimeData().hasFormat(specialMimeType): return filenameBytes=event.mimeData().data(specialMimeType) filename=QTextCodec.codecForName("utf-16").toUnicode(filenameBytes) print unicode(filename).encode("gbk")
可惜的是,目前我还不知道要怎么拖拉一个文件到文件管理器里面。
标题无“转载”即原创文章,版权所有。转载请注明来源:http://hgoldfish.com/blogs/article/54/。
老鱼(July 19, 2014, 9:12 p.m.)
直接用text/uri-list会更好一些。