QT下实现Drag-Drop是极其容易的,下面给大家介绍一下。
所谓拖动,自动有一个源窗口,一个目标窗口,不过有时候源窗口与目的窗口是同一个窗口。
源窗口
在鼠标Press的时候,记录起始点为dragPosition(此为成员变量);在Move的时候,检测与起始点的距离,当拖动一定距离的时候,认为开启了一个拖动操作。按下面例子,鼠标会为成拖动的样式,并有一个图片显示被拖动的物体的轮廓。
void HostTree::mouseMoveEvent ( QMouseEvent * event )
{
if (!(event->buttons() & Qt::LeftButton))
return;
if ((event->pos() - dragPosition).manhattanLength() < QApplication::startDragDistance())
return;
QDrag *drag = new QDrag(this);
QMimeData *mimeData = new QMimeData;
// 把ip地址传出
mimeData->setData("custom/host_free", ...设置一个ByteArray... );
drag->setMimeData(mimeData);
// 设置图片
QPixmap drag_img(120, 18);
QPainter painter(&drag_img);
painter.drawText(QRectF(0,0, 120,18), ... 拖动时图片信息.. , QTextOption(Qt::AlignVCenter));
drag->setPixmap(drag_img);
Qt::DropAction resultAction = drag->exec(Qt::MoveAction);
if(resultAction == Qt::MoveAction)
{
// 确认移动操作
// 该操作已经被目标操作接受,且操作类型为MOVE,一般来说应该把被拖动的物体从源窗口删除
}
//QTreeWidget::mouseMoveEvent(event);
}
void HostTree::mousePressEvent ( QMouseEvent * event )
{
if (event->button() == Qt::LeftButton)
{
dragItem = itemAt(event->pos());
dragPosition = event->pos();
}
QTreeWidget::mousePressEvent(event);
}
目标窗口
首先这个Widget要设置
setAcceptDrops(true);
然后要重写drop的4大操作, 即enter leave move drop。
首先说enter,表示拖动操作进入本窗口,是接受还是拒绝,是一个需要思考的问题。其标准是检测该其mine data的格式, 即hasFormat()来判断。如果该event被ignore,则鼠标在窗口中会显示一个forbidden状态的圆圈,表示禁止拖进来。
void TopoTree::dragEnterEvent ( QDragEnterEvent * event )
{
//qDebug("dragEnterEvent: enter drag mode ............");
if(event->mimeData()->hasFormat("custom/host_free"))
{
m_dragMode = 1;
event->acceptProposedAction();
}
else
{
event->ignore();
QTreeWidget::dragEnterEvent(event);
}
}
第2个是leave,表示离开本窗口,即用户拖动东西进来,但是没有drop放下来又走了。那么把m_dragMode=0回到原状态。这个m_dragMode你爱加不加,不过一般会用到此状态。
void TopoTree::dragLeaveEvent ( QDragLeaveEvent * event )
{
//qDebug("exit topotree, exit drag mode ............");
m_dragMode = 0;
QTreeWidget::dragLeaveEvent(event);
}
第3个是move,用户拖动东西在目标窗口内游荡,在拖到某此点位时,应提示允许其drop放下。比如目标窗口里有若干个坑,那么当鼠标over到坑上时,就应该提示这里可以drop并改变鼠标形状。
void TopoTree::dragMoveEvent ( QDragMoveEvent * event )
{
if(event->mimeData()->hasFormat("custom/host_free"))
{
QTreeWidgetItem* itemOver = itemAt(event->pos());
if(itemOver == NULL)
{
}
else
{
// accept
event->acceptProposedAction();
//QTreeWidget::dragMoveEvent(event);
return;
}
}
event->ignore();
QTreeWidget::dragMoveEvent(event);
}
最后一个是drop,这个是重头戏,即某个点位用户放开了鼠标完成drop操作。一般来说,应该解析出该drag所携带的 data ,然后做一个插入操作。调用acceptProposedAction()来通知源窗口,说此操作已经被接受,源窗口应于此时做一个删除/复制操作。
void TopoTree::dropEvent ( QDropEvent * event )
{
if(event->mimeData()->hasFormat("custom/host_free"))
{
QTreeWidgetItem* itemOver = itemAt(event->pos());
if(itemOver != NULL)
{
// 接收此MoveAction,插入节点
// 提取drag中携带的信息
QByteArray data = event->mimeData()->data("custom/host_free");
// 新建节点
this->setCurrentItem(item); // 设置为当前选中
this->m_dragMode = 0; // 结束drag mode
event->acceptProposedAction();
//QTreeWidget::dropEvent(event);
return;
}
}
event->ignore();
QTreeWidget::dropEvent(event);
}
---------------------
作者:阿发你好
来源:CSDN
原文:https://blog.csdn.net/iamshaofa/article/details/17629897?utm_medium=distribute.pc_relevant.none-task-blog-searchFromBaidu-3.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-searchFromBaidu-3.control
版权声明:本文为作者原创文章,转载请附上博文链接!