qt 拖动 讲解 QDrag

QT下实现Drag-Drop是极其容易的,下面给大家介绍一下。

所谓拖动,自动有一个源窗口,一个目标窗口,不过有时候源窗口与目的窗口是同一个窗口。

源窗口

在鼠标Press的时候,记录起始点为dragPosition(此为成员变量);在Move的时候,检测与起始点的距离,当拖动一定距离的时候,认为开启了一个拖动操作。按下面例子,鼠标会为成拖动的样式,并有一个图片显示被拖动的物体的轮廓。

  1. void HostTree::mouseMoveEvent ( QMouseEvent * event )  
  2. {  
  3.     if (!(event->buttons() & Qt::LeftButton))  
  4.         return;  
  5.   
  6.     if ((event->pos() - dragPosition).manhattanLength()  < QApplication::startDragDistance())  
  7.         return;  
  8.       
  9.     QDrag *drag = new QDrag(this);  
  10.     QMimeData *mimeData = new QMimeData;  
  11.   
  12.     // 把ip地址传出  
  13.     mimeData->setData("custom/host_free", ...设置一个ByteArray... );  
  14.     drag->setMimeData(mimeData);  
  15.   
  16.     // 设置图片  
  17.     QPixmap drag_img(120, 18);  
  18.     QPainter painter(&drag_img);  
  19.     painter.drawText(QRectF(0,0, 120,18), ... 拖动时图片信息.. , QTextOption(Qt::AlignVCenter));  
  20.     drag->setPixmap(drag_img);  
  21.   
  22.     Qt::DropAction resultAction = drag->exec(Qt::MoveAction);  
  23.     if(resultAction == Qt::MoveAction)  
  24.     {  
  25.         // 确认移动操作  
  26.         // 该操作已经被目标操作接受,且操作类型为MOVE,一般来说应该把被拖动的物体从源窗口删除  
  27.     }  
  28.   
  29.     //QTreeWidget::mouseMoveEvent(event);  
  30. }  
  31.   
  32. void HostTree::mousePressEvent ( QMouseEvent * event )   
  33. {  
  34.     if (event->button() == Qt::LeftButton)  
  35.     {  
  36.         dragItem = itemAt(event->pos());  
  37.         dragPosition = event->pos();  
  38.     }  
  39.   
  40.     QTreeWidget::mousePressEvent(event);      
  41. }  


目标窗口

首先这个Widget要设置

  1. setAcceptDrops(true);  


然后要重写drop的4大操作, 即enter leave move drop。

首先说enter,表示拖动操作进入本窗口,是接受还是拒绝,是一个需要思考的问题。其标准是检测该其mine data的格式, 即hasFormat()来判断。如果该event被ignore,则鼠标在窗口中会显示一个forbidden状态的圆圈,表示禁止拖进来。

  1. void  TopoTree::dragEnterEvent ( QDragEnterEvent * event )   
  2. {  
  3.     //qDebug("dragEnterEvent: enter drag mode ............");  
  4.   
  5.     if(event->mimeData()->hasFormat("custom/host_free"))  
  6.     {  
  7.         m_dragMode = 1;  
  8.         event->acceptProposedAction();  
  9.     }  
  10.     else  
  11.     {  
  12.         event->ignore();  
  13.         QTreeWidget::dragEnterEvent(event);  
  14.     }  
  15. }  

第2个是leave,表示离开本窗口,即用户拖动东西进来,但是没有drop放下来又走了。那么把m_dragMode=0回到原状态。这个m_dragMode你爱加不加,不过一般会用到此状态。

  1. void  TopoTree::dragLeaveEvent ( QDragLeaveEvent * event )   
  2. {  
  3.     //qDebug("exit topotree, exit drag mode ............");  
  4.     m_dragMode = 0;  
  5.   
  6.     QTreeWidget::dragLeaveEvent(event);  
  7. }  

第3个是move,用户拖动东西在目标窗口内游荡,在拖到某此点位时,应提示允许其drop放下。比如目标窗口里有若干个坑,那么当鼠标over到坑上时,就应该提示这里可以drop并改变鼠标形状。

  1. void  TopoTree::dragMoveEvent ( QDragMoveEvent * event )   
  2. {  
  3.     if(event->mimeData()->hasFormat("custom/host_free"))  
  4.     {  
  5.         QTreeWidgetItem* itemOver = itemAt(event->pos());  
  6.         if(itemOver == NULL)  
  7.         {  
  8.         }  
  9.         else  
  10.         {  
  11.             // accept  
  12.             event->acceptProposedAction();  
  13.             //QTreeWidget::dragMoveEvent(event);  
  14.             return;  
  15.         }  
  16.     }  
  17.       
  18.     event->ignore();  
  19.     QTreeWidget::dragMoveEvent(event);  
  20. }  


最后一个是drop,这个是重头戏,即某个点位用户放开了鼠标完成drop操作。一般来说,应该解析出该drag所携带的 data ,然后做一个插入操作。调用acceptProposedAction()来通知源窗口,说此操作已经被接受,源窗口应于此时做一个删除/复制操作。

  1. void  TopoTree::dropEvent ( QDropEvent * event )   
  2. {  
  3.     if(event->mimeData()->hasFormat("custom/host_free"))  
  4.     {  
  5.         QTreeWidgetItem* itemOver = itemAt(event->pos());  
  6.         if(itemOver != NULL)  
  7.         {  
  8.             // 接收此MoveAction,插入节点  
  9.               
  10.             // 提取drag中携带的信息  
  11.             QByteArray data = event->mimeData()->data("custom/host_free");  
  12.             // 新建节点  
  13.             this->setCurrentItem(item); // 设置为当前选中  
  14.             this->m_dragMode = 0; // 结束drag mode  
  15.             event->acceptProposedAction();  
  16.             //QTreeWidget::dropEvent(event);  
  17.             return;  
  18.         }  
  19.     }  
  20.   
  21.     event->ignore();  
  22.     QTreeWidget::dropEvent(event);  
  23. }  


怎么样,讲得够清楚了吗,呵呵。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值