主要学习网站:https://www.devbean.net/2013/05/qt-study-road-2-dnd/
所言的拖放就是拖动和释放,英文解释为Drag and Drop,这是两个事件;
拖动是鼠标将所指文件进行在应用之间挪位,在此期间一直调用dragEnterEvent接口。
释放则是所指物在放下时,程序进行反应,调用dropEvent接口。
接下来我们看一看如何拖放一个txt文件到主界面下,并在文本控件中显示文本内容。
·Qt中新建一个窗口项目。
使用QMainWindow或者QWidget都可。
只创建一个QTextEdit对象即可。
构造函数
MainWidget::MainWidget(QWidget *parent) : QWidget(parent)
{
resize(400,300);
textEdit = new QTextEdit(this);
}
·做一些准备工作
在构造函数中添加申明:textEdit不接受释放,QWidget或者QMainWindw主窗口接受释放。
textEdit->setAcceptDrops(false);
setAcceptDrops(true);
(默认情况下textEdit是接受拖放的,主界面不接受,这样做的目的是将事件交给主界面去做。也就是说你不需要将文件拖到文本框中,只要拖到程序任意界面都可。当然你可以不关注这个事情。)
在类中重写两个函数:
void dragEnterEvent(QDragEnterEvent *event) override;
void dropEvent(QDropEvent *event) override;
顾名思义,这是两个事件函数。
·拖动事件函数
void MainWidget::dragEnterEvent(QDragEnterEvent *event)
{
if(event->mimeData()->hasFormat("text/uri-list"))
event->acceptProposedAction();
}
在原文中是这么解释的:
当用户将对象拖动到组件上面时,系统会回调dragEnterEvent()函数。如果我们在事件处理代码中调用acceptProposeAction()函数,就可以向用户暗示,你可以将拖动的对象放在这个组件上。默认情况下,组件是不会接受拖放的。如果我们调用了这个函数,那么 Qt 会自动以光标样式的变化来提示用户是否可以将对象放在组件上。在这里,我们希望告诉用户,窗口可以接受拖放,但是我们仅接受某一种类型的文件,而不是全部文件。我们首先检查拖放文件的 MIME 类型信息。MIME 类型由 Internet Assigned Numbers Authority (IANA) 定义,Qt 的拖放事件使用 MIME 类型来判断拖放对象的类型。关于 MIME 类型的详细信息,请参考 http://www.iana.org/assignments/media-types/。MIME 类型为 text/uri-list 通常用来描述一个 URI 列表。这些 URI 可以是文件名,可以是 URL 或者其它的资源描述符。如果发现用户拖放的是一个 text/uri-list 数据(即文件名),我们便接受这个动作。
其实就是说,在你拖放到Qt应用中时,光标会产生提示,表示可以在此释放。
format中文解释为样式,样板。所以从代码里就可以看出意思是在鼠标拖动过程中,一直调用该事件函数;并且判断是否包含“text/uri-list”样式信息,如果有,就设置光标可释放。
·释放事件函数
void MainWidget::dropEvent(QDropEvent *event)
{
QList<QUrl> urls = event->mimeData()->urls(); //将实践中的url罗列出来
if(urls.isEmpty()) //判断是否为空
return;
QString filename = urls.first().toLocalFile(); //.first()直接QString内容是file://+路径,所以用.toLocalFile()函数
QFile file(filename); //以下是常规的读文件操作
if(file.open(QIODevice::ReadOnly))
textEdit->setText(file.readAll());
file.close();
}
具体代码解释都有。