QT:拖拽文字图片

一、简介

       首先选择窗体显示风格,接着显现拖拽效果,文字和图标都可以作为拖拽的对象,在窗体中的文字图标可以拖拽到窗口的任意位置,它们在两个独立运行的程序间也可相互拖拽(此时是复制一份到拖拽目的程序窗口中),文字拖拽的范围更广(须注意字符集的转换)。本文解决这种比较神秘的效果,熟悉拖拽的基本流程。

二、运行图

(1)总体效果图如下图1所示。左边风格设置,中间文字区,右侧拖拽区。

(2)拖拽的实现过程,如下图2所示。

实现拖拽最基本的工作有3部分:一、在可拖拽对象的mousePressEvent()函数中构建QDrag对象,并调用start()函数等待DropAction的返回。二、在放置可拖拽对象的容器类中,实现dragEnterEvent()函数,判断并设置应采用何种DropAction,返回给start()函数。三、在放置可拖拽对象的容器类中,实现dragEnterEvent()函数,创建一个新的可拖拽对象并在当前鼠标位置进行显示,同时判断并设置应采用何种DropAction,返回给start()函数。

三、详解

1、窗体风格

(1)系统支持的7中窗体风格,如下图所示。

[cpp]  view plain  copy
  1. QLabel *label = new QLabel(QObject::tr("窗体风格:"));  
  2. QComboBox *styleComboBox = new QComboBox;  
  3. styleComboBox->addItems(QStyleFactory::keys());  
  4. styleComboBox->setCurrentIndex(5);  
  5.   
  6. void DragWidget::slotChangeStyle(QString style)  
  7. {  
  8.     QApplication::setStyle(QStyleFactory::create(style));  
  9.     QApplication::setPalette(QApplication::style()->standardPalette());  
  10. }  
      QStyleFactory::keys()获得当前系统支持的窗体风格,QApplication的setStyle()函数设置为刚创建的风格,调用setPalette()完成窗体显示的改变。

2、拖拽文字

(1)同一实例程序拖拽(移动)

中间控件的文字都拖放到右侧,通过光标的选择分解它们。

[cpp]  view plain  copy
  1. void DragLabel::mousePressEvent(QMouseEvent * e)  
  2. {  
  3.      QString str = text();  
  4.      QPixmap pix;  
  5.      pix = pix.grabWidget(this);  
  6.   
  7.      QByteArray data;  
  8.      QDataStream stream(&data,QIODevice::WriteOnly);  
  9.      stream << str << QPoint(e->pos()-rect().topLeft());  
  10.      QMimeData *mimeData = new QMimeData;  
  11.      mimeData->setData("Drag-Text",data);  
  12.      mimeData->setText(str);  
  13.   
  14.      QDrag *drag = new QDrag(this);  
  15.      drag->setMimeData(mimeData);  
  16.      drag->setHotSpot(QPoint(e->pos() - rect().topLeft()));  
  17.      drag->setPixmap(pix);  
  18.   
  19.      hide();  
  20.   
  21.      Qt::DropAction dropAction = drag->start(Qt::CopyAction | Qt::MoveAction);  
  22.   
  23.      if (dropAction == Qt::MoveAction)  
  24.          close();  
  25.      else  
  26.          show();  
  27. }  

(2)不同实例程序拖拽(复制)

左侧文字向右侧程序中拖拽。


(3)外部程序拖拽交互

文本间的来回移动,以空格为分隔标志,也可以复制一段文字,但暂时没法控制文字的长度显示。

[cpp]  view plain  copy
  1. void DragWidget::dropEvent(QDropEvent *e)  
  2. {  
  3.     if (e->mimeData()->hasFormat("Drag-Icon")) {  
  4.         QByteArray data = e->mimeData()->data("Drag-Icon");  
  5.         QDataStream stream(&data,QIODevice::ReadOnly);  
  6.         QPixmap pix;  
  7.         QPoint offset;  
  8.         stream >> pix >> offset;  
  9.   
  10.         DragIcon *icon = new DragIcon(pix,this);  
  11.         icon->move(e->pos() - offset);  
  12.         icon->resize(50, 50);  
  13.         icon->show();  
  14.         if (children().contains(e->source())) {  
  15.           e->setDropAction(Qt::MoveAction);  
  16.           e->accept();  
  17.         }  
  18.         else e->acceptProposedAction();  
  19.     }  
  20.     else if (e->mimeData()->hasFormat("Drag-Text"))  
  21.     {  
  22.         QByteArray data = e->mimeData()->data("Drag-Text");  
  23.         QDataStream stream(&data,QIODevice::ReadOnly);  
  24.         QString text;  
  25.         QPoint offset;  
  26.         stream >> text >> offset;  
  27.   
  28.         DragLabel *label = new DragLabel(text,this);  
  29.         label->move(e->pos() - offset);  
  30.         label->show();  
  31.   
  32.         if (children().contains(e->source())) {  
  33.           e->setDropAction(Qt::MoveAction);  
  34.           e->accept();  
  35.         }  
  36.         else  e->acceptProposedAction();  
  37.     }  
  38.     else if (e->mimeData()->hasText())  
  39.     {  
  40.         QStringList strList = e->mimeData()->text().split(QRegExp("\\s+"),QString::SkipEmptyParts);  
  41.         QPoint pos = e->pos();  
  42.   
  43.         foreach(QString str, strList) {  
  44.           DragLabel *dragLabel = new DragLabel(str,this);  
  45.           dragLabel->move(pos);  
  46.           dragLabel->show();  
  47.           pos += QPoint(dragLabel->width(),0);  
  48.         }  
  49.        if (children().contains(e->source())) {  
  50.           e->setDropAction(Qt::MoveAction);  
  51.           e->accept();  
  52.        }  
  53.        else {  
  54.          e->acceptProposedAction();  
  55.        }  
  56.     }  
  57.     else {  
  58.         e->ignore();  
  59.     }  
  60. }  
     上代码的if判断可知,拖拽文本不仅支持自定义的格式hasFormat("Drag-Text"),而且还支持简单的文本格式e->mimeData()->hasText(),因此其他的文本也可来回共享(图片仅支持自己的格式)。

3、拖拽图标

(1)同一实例程序拖拽(移动)

[cpp]  view plain  copy
  1. void DragIcon::mousePressEvent(QMouseEvent * e)  
  2. {  
  3.     if(e->button() == Qt::LeftButton)  
  4.         startPos = e->pos();  
  5. }  
  6.   
  7. void DragIcon::mouseMoveEvent(QMouseEvent * e)  
  8. {  
  9.     if (!e->buttons()&Qt::LeftButton)  
  10.         return;  
  11.     if ((e->pos() - startPos).manhattanLength() < QApplication::startDragDistance())  
  12.         return;  
  13.   
  14.     QPixmap pix = *pixmap();  
  15.   
  16.     QByteArray data;  
  17.     QDataStream stream(&data,QIODevice::WriteOnly);  
  18.     stream << pix << QPoint(e->pos()-rect().topLeft());  
  19.     QMimeData *mimeData = new QMimeData;  
  20.     mimeData->setData("Drag-Icon",data);  
  21.   
  22.     QDrag *drag = new QDrag(this);  
  23.     drag->setMimeData(mimeData);  
  24.     drag->setHotSpot(QPoint(e->pos() - rect().topLeft()));  
  25.     drag->setPixmap(pix);  
  26.   
  27.     hide();  
  28.   
  29.     Qt::DropAction dropAction = drag->start(Qt::CopyAction | Qt::MoveAction);  
  30.   
  31.     if (dropAction == Qt::MoveAction)  
  32.         close();  
  33.     else  
  34.         show();  
  35. }  
  36. void DragWidget::dragEnterEvent(QDragEnterEvent *e)  
  37. {  
  38.     if (e->mimeData()->hasText() || e->mimeData()->hasFormat("Drag-Icon"))  
  39.     {  
  40.         if(children().contains(e->source()))  
  41.         {  
  42.             e->setDropAction(Qt::MoveAction);  
  43.             e->accept();  
  44.     }  
  45.     else  
  46.         e->acceptProposedAction();  
  47.     }  
  48. }  
  49.   
  50. void DragWidget::dragMoveEvent(QDragMoveEvent *e)  
  51. {  
  52.     if (e->mimeData()->hasText() || e->mimeData()->hasFormat("Drag-Icon"))  
  53.     {  
  54.         if(children().contains(e->source()))  
  55.         {  
  56.             e->setDropAction(Qt::MoveAction);  
  57.             e->accept();  
  58.     }  
  59.     else  
  60.         e->acceptProposedAction();  
  61.     }  
  62. }  
在本窗口的右侧组件中可以来回拖放图片,因改程序自定义了图片格式hasFormat("Drag-Icon"),因此其他的图片无法拖入。

(2)不同实例程序拖拽(复制)

[cpp]  view plain  copy
  1. void DragWidget::dropEvent(QDropEvent *e)  
  2. {  
  3.     if (e->mimeData()->hasFormat("Drag-Icon")) {  
  4.         QByteArray data = e->mimeData()->data("Drag-Icon");  
  5.         QDataStream stream(&data,QIODevice::ReadOnly);  
  6.         QPixmap pix;  
  7.         QPoint offset;  
  8.         stream >> pix >> offset;  
  9.   
  10.         DragIcon *icon = new DragIcon(pix,this);  
  11.         icon->move(e->pos() - offset);  
  12.         icon->resize(50, 50);  
  13.         icon->show();  
  14.         if (children().contains(e->source())) {  
  15.           e->setDropAction(Qt::MoveAction);  
  16.           e->accept();  
  17.         }  
  18.         else e->acceptProposedAction();  
  19.     }  
  20. //.........................  
  21. }  

四、总结

(1)本文仅简单总结,还可以扩展到类似于剪贴板的机制,拖拽文字可以加入字符集的转换,拖拽图片可以考虑外部图片的转换,还可以扩展到文件的拖拽。

(2)对部分代码的理解也是不太深入,还得进一步深究。

(3)源码已经打包上传到csdn上可登录下载(http://download.csdn.net/detail/taiyang1987912/7574413)。 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值