QT:拖拽文字图片
一、简介
首先选择窗体显示风格,接着显现拖拽效果,文字和图标都可以作为拖拽的对象,在窗体中的文字图标可以拖拽到窗口的任意位置,它们在两个独立运行的程序间也可相互拖拽(此时是复制一份到拖拽目的程序窗口中),文字拖拽的范围更广(须注意字符集的转换)。本文解决这种比较神秘的效果,熟悉拖拽的基本流程。
二、运行图
(1)总体效果图如下图1所示。左边风格设置,中间文字区,右侧拖拽区。
(2)拖拽的实现过程,如下图2所示。
实现拖拽最基本的工作有3部分:一、在可拖拽对象的mousePressEvent()函数中构建QDrag对象,并调用start()函数等待DropAction的返回。二、在放置可拖拽对象的容器类中,实现dragEnterEvent()函数,判断并设置应采用何种DropAction,返回给start()函数。三、在放置可拖拽对象的容器类中,实现dragEnterEvent()函数,创建一个新的可拖拽对象并在当前鼠标位置进行显示,同时判断并设置应采用何种DropAction,返回给start()函数。
三、详解
1、窗体风格
(1)系统支持的7中窗体风格,如下图所示。
- QLabel *label = new QLabel(QObject::tr("窗体风格:"));
- QComboBox *styleComboBox = new QComboBox;
- styleComboBox->addItems(QStyleFactory::keys());
- styleComboBox->setCurrentIndex(5);
- void DragWidget::slotChangeStyle(QString style)
- {
- QApplication::setStyle(QStyleFactory::create(style));
- QApplication::setPalette(QApplication::style()->standardPalette());
- }
2、拖拽文字
(1)同一实例程序拖拽(移动)
中间控件的文字都拖放到右侧,通过光标的选择分解它们。
- void DragLabel::mousePressEvent(QMouseEvent * e)
- {
- QString str = text();
- QPixmap pix;
- pix = pix.grabWidget(this);
- QByteArray data;
- QDataStream stream(&data,QIODevice::WriteOnly);
- stream << str << QPoint(e->pos()-rect().topLeft());
- QMimeData *mimeData = new QMimeData;
- mimeData->setData("Drag-Text",data);
- mimeData->setText(str);
- QDrag *drag = new QDrag(this);
- drag->setMimeData(mimeData);
- drag->setHotSpot(QPoint(e->pos() - rect().topLeft()));
- drag->setPixmap(pix);
- hide();
- Qt::DropAction dropAction = drag->start(Qt::CopyAction | Qt::MoveAction);
- if (dropAction == Qt::MoveAction)
- close();
- else
- show();
- }
(2)不同实例程序拖拽(复制)
左侧文字向右侧程序中拖拽。
(3)外部程序拖拽交互
文本间的来回移动,以空格为分隔标志,也可以复制一段文字,但暂时没法控制文字的长度显示。
- void DragWidget::dropEvent(QDropEvent *e)
- {
- if (e->mimeData()->hasFormat("Drag-Icon")) {
- QByteArray data = e->mimeData()->data("Drag-Icon");
- QDataStream stream(&data,QIODevice::ReadOnly);
- QPixmap pix;
- QPoint offset;
- stream >> pix >> offset;
- DragIcon *icon = new DragIcon(pix,this);
- icon->move(e->pos() - offset);
- icon->resize(50, 50);
- icon->show();
- if (children().contains(e->source())) {
- e->setDropAction(Qt::MoveAction);
- e->accept();
- }
- else e->acceptProposedAction();
- }
- else if (e->mimeData()->hasFormat("Drag-Text"))
- {
- QByteArray data = e->mimeData()->data("Drag-Text");
- QDataStream stream(&data,QIODevice::ReadOnly);
- QString text;
- QPoint offset;
- stream >> text >> offset;
- DragLabel *label = new DragLabel(text,this);
- label->move(e->pos() - offset);
- label->show();
- if (children().contains(e->source())) {
- e->setDropAction(Qt::MoveAction);
- e->accept();
- }
- else e->acceptProposedAction();
- }
- else if (e->mimeData()->hasText())
- {
- QStringList strList = e->mimeData()->text().split(QRegExp("\\s+"),QString::SkipEmptyParts);
- QPoint pos = e->pos();
- foreach(QString str, strList) {
- DragLabel *dragLabel = new DragLabel(str,this);
- dragLabel->move(pos);
- dragLabel->show();
- pos += QPoint(dragLabel->width(),0);
- }
- if (children().contains(e->source())) {
- e->setDropAction(Qt::MoveAction);
- e->accept();
- }
- else {
- e->acceptProposedAction();
- }
- }
- else {
- e->ignore();
- }
- }
3、拖拽图标
(1)同一实例程序拖拽(移动)
- void DragIcon::mousePressEvent(QMouseEvent * e)
- {
- if(e->button() == Qt::LeftButton)
- startPos = e->pos();
- }
- void DragIcon::mouseMoveEvent(QMouseEvent * e)
- {
- if (!e->buttons()&Qt::LeftButton)
- return;
- if ((e->pos() - startPos).manhattanLength() < QApplication::startDragDistance())
- return;
- QPixmap pix = *pixmap();
- QByteArray data;
- QDataStream stream(&data,QIODevice::WriteOnly);
- stream << pix << QPoint(e->pos()-rect().topLeft());
- QMimeData *mimeData = new QMimeData;
- mimeData->setData("Drag-Icon",data);
- QDrag *drag = new QDrag(this);
- drag->setMimeData(mimeData);
- drag->setHotSpot(QPoint(e->pos() - rect().topLeft()));
- drag->setPixmap(pix);
- hide();
- Qt::DropAction dropAction = drag->start(Qt::CopyAction | Qt::MoveAction);
- if (dropAction == Qt::MoveAction)
- close();
- else
- show();
- }
- void DragWidget::dragEnterEvent(QDragEnterEvent *e)
- {
- if (e->mimeData()->hasText() || e->mimeData()->hasFormat("Drag-Icon"))
- {
- if(children().contains(e->source()))
- {
- e->setDropAction(Qt::MoveAction);
- e->accept();
- }
- else
- e->acceptProposedAction();
- }
- }
- void DragWidget::dragMoveEvent(QDragMoveEvent *e)
- {
- if (e->mimeData()->hasText() || e->mimeData()->hasFormat("Drag-Icon"))
- {
- if(children().contains(e->source()))
- {
- e->setDropAction(Qt::MoveAction);
- e->accept();
- }
- else
- e->acceptProposedAction();
- }
- }
(2)不同实例程序拖拽(复制)
- void DragWidget::dropEvent(QDropEvent *e)
- {
- if (e->mimeData()->hasFormat("Drag-Icon")) {
- QByteArray data = e->mimeData()->data("Drag-Icon");
- QDataStream stream(&data,QIODevice::ReadOnly);
- QPixmap pix;
- QPoint offset;
- stream >> pix >> offset;
- DragIcon *icon = new DragIcon(pix,this);
- icon->move(e->pos() - offset);
- icon->resize(50, 50);
- icon->show();
- if (children().contains(e->source())) {
- e->setDropAction(Qt::MoveAction);
- e->accept();
- }
- else e->acceptProposedAction();
- }
- //.........................
- }
四、总结
(1)本文仅简单总结,还可以扩展到类似于剪贴板的机制,拖拽文字可以加入字符集的转换,拖拽图片可以考虑外部图片的转换,还可以扩展到文件的拖拽。
(2)对部分代码的理解也是不太深入,还得进一步深究。
(3)源码已经打包上传到****上可登录下载(http://download.****.net/detail/taiyang1987912/7574413)。