概述
- Qt的拖放系统提供了一种方便的方式,在应用程序中实现拖放操作,从而实现简单的数据交换。使用Qt拖放系统,用户可以将某些数据从一个部件或进程中“拖动”到另一个位置,然后释放它,使其成为新位置的副本或移动。当然,Qt拖放系统也支持不同应用程序之间的拖放。
- Qt拖放系统设计理念基于事件驱动模型,该模型采用QDrag类作为拖动操作事件的处理器。QDrag管理拖动窗口和委托(Dummy Widget),该委托用以在主窗口上蒙板以显示相对于光标对象的相关信息。
1 拖放原理
- 在开始拖拽之前,启用一个QDrag对象,并将待传输的数据存储在QMimeData对象中以便传输。
- 拖动的数据会被存储为 MIME 类型
- 拖动事件开始后,QDrag开始跟踪鼠标的位置并更新拖动窗口和客户端委托,以提供关于所选数据的视觉反馈。
- 当鼠标移动过程中,拖动窗口可以被调整大小并随着鼠标移动而更新。委托通常保持小而显示有关所选项目的基本信息和表示图像。
- 当停止拖动时,Qt会触发相应的dragDropEvent()或dropEvent()事件(这取决于应用程序的设置)。任何事件都包含一个QDropEvent参数来描述源拖动操作传输过来的数据。
- 需要重载一些函数,如dragEnterEvent()、dragMoveEvent()和dropEvent()等,以根据实际需求处理所有响应的事件,并实现所需的拖放行为。
2 简单拖放步骤
- 在需要接受放下数据的部件上调用
setAcceptDrops()
函数以使该部件能接受拖放事件。
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
DragDropButton *btn1 = new DragDropButton("AAA", this);
DragDropButton *btn2 = new DragDropButton("BBB", this);
btn1->move((width() - btn1->width()) / 3,
(height() - btn1->height()) / 2);
btn2->move(btn1->geometry().right() + 10, btn1->geometry().top());
btn1->setAcceptDrops(false);
btn2->setAcceptDrops(true); // 接受放下事件
}
- 启动拖放
通常是在 mousePressEvent()或 mouseMoveEvent()函数中启动拖放,启动拖放就是调用 QDrag 对象的 exec()函数,因此也可以在 keyPressEvent()等函数中启动拖放(很少这样做)。在此步把需要拖动的数据保存在 QMimeData 对象中。
void DragDropButton::mousePressEvent(QMouseEvent *event)
{
Q_UNUSED(event)
QDrag *drag = new QDrag(this);
// 拖放的内容可自行定义
QMimeData *mimeData = new QMimeData;
mimeData->setText(this->text());
drag->setMimeData(mimeData);
drag->exec(Qt::CopyAction); // 启动拖放操作
}
- 重新实现需要接受放下数据的部件的 dragEnterEvent()事件处理函数。
void DragDropButton::dragEnterEvent(QDragEnterEvent *event)
{
event->accept(); // 接受拖动进入事件
}
- 根据需要重新实现 dragMoveEvent 或 dropEvent()函数。
void DragDropButton::dropEvent(QDropEvent *event)
{
this->setText(event->mimeData()->text());
}