Qt之拖放
2016-05-04 17:00
645 查看
Qt之 拖放(drag 和 drop)
拖放是应用程序内或者应用程序之间数据传递的一种方式。通常是提供数据的复制和移动。拖放主要包括拖动和放下。有些窗口可能只需要提供拖动功能,有些窗口可能只需要放下,有些窗口可能两者功能都需要具备。Qt的一些控件不需要进行任何设置,就具备拖放功能,比如QLineEdit、QTextEdit。QLineEdit可以接受拖动过来的字符串,而QTextEdit可以接受拖动的字符串以及拖动文件的路径。所需要做的就是创建一个对象,然后显示,如下:
QLineEdit lineEdit;
lineEdit.show();
QTextEdit textEdit;
textEdit.show();
QLineEdit接受文字拖放,测试效果:
QTextEdit接受文件拖放,显示文件的路径,支持多个文件一起拖放,测试效果:
QWidget实现拖放,需要设置接受拖放,
setAcceptDrops(true);
并实现下面事件:
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
如果我们只需要QWidget接受放下,那么就不需要实现:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
这两个事件主要是,当我们需要QWidget实现拖动时才需要的。
QApplication提供了两种方式来启动一个拖动操作:
QApplication::startDragDistance():通过鼠标移动的距离来判断是否启动拖放,默认是10个像素点。但也可以通过static void setStartDragDistance(int l);来进行自定义开始拖放的距离。
QApplication::startDragTime():通过鼠标点击的时长来判断是否启动拖放,默认是500ms。也可以通过static void setStartDragTime(int ms);来自定义按压时长。
为了实现拖放,我们需要在mousePressEvent内记录鼠标按下的坐标点或者时间点,然后在mouseMoveEvent判断鼠标移动的距离或者按压时间是否满足拖放要求,从而启动拖放。
执行拖放操作,我们需要创建一个QDrag对象,此对象包含QMimeData,这里保存着我们需要拖动的数据。
示例:
void QDragDrop::mousePressEvent(QMouseEvent *event) { __super::mousePressEvent(event); mStartPoint = event->pos();//起点 } void QDragDrop::mouseMoveEvent(QMouseEvent *event) { __super::mouseMoveEvent(event); if ((event->pos() - mStartPoint).manhattanLength() > QApplication::startDragDistance())//判断是否执行拖动 { QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; QByteArray byteArray;//存储数据 QDataStream stream(&byteArray,QIODevice::WriteOnly);//流,写数据 stream << QImage("C:\\Users\\dlp\\Desktop\\2.png");//读取一个图片的数据 mimeData->setData("MyImage", byteArray);//设置数据 drag->setMimeData(mimeData);//设置数据 drag->exec(Qt::MoveAction);//执行拖动 delete drag; } }上述示例,读取了一个图片的数据保存在QMimeData里面,作为要传递的数据。并且设置了自定义格式"MyImage"。
效果如下:
示例代码如下:
#ifndef QDRAGDROP_H #define QDRAGDROP_H #include <QtWidgets/QWidget> #include <QMouseEvent> #include <QHBoxLayout> class QDragDrop : public QWidget { Q_OBJECT public: QDragDrop(QWidget *parent = 0); ~QDragDrop(); protected: void dragEnterEvent(QDragEnterEvent *event); void dragMoveEvent(QDragMoveEvent *event); void dropEvent(QDropEvent *event); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); private: QPoint mStartPoint; QHBoxLayout *m_HBox; }; #endif // QDRAGDROP_H
#include "qdragdrop.h"
#include <QApplication>
#include <QDrag>
#include <QMimeData>
#include <QLabel>
QDragDrop::QDragDrop(QWidget *parent)
: QWidget(parent)
{
mStartPoint = QPoint(0, 0);
m_HBox = new QHBoxLayout(this);
setAcceptDrops(true);
setWindowTitle("QWidget");
}
QDragDrop::~QDragDrop()
{
}
void QDragDrop::mousePressEvent(QMouseEvent *event) { __super::mousePressEvent(event); mStartPoint = event->pos();//起点 } void QDragDrop::mouseMoveEvent(QMouseEvent *event) { __super::mouseMoveEvent(event); if ((event->pos() - mStartPoint).manhattanLength() > QApplication::startDragDistance())//判断是否执行拖动 { QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; QByteArray byteArray;//存储数据 QDataStream stream(&byteArray,QIODevice::WriteOnly);//流,写数据 stream << QImage("C:\\Users\\dlp\\Desktop\\2.png");//读取一个图片的数据 mimeData->setData("MyImage", byteArray);//设置数据 drag->setMimeData(mimeData);//设置数据 drag->exec(Qt::MoveAction);//执行拖动 delete drag; } }
void QDragDrop::dragEnterEvent(QDragEnterEvent *event)
{
__super::dragEnterEvent(event);
if (event->mimeData()->hasFormat("MyImage"))
event->acceptProposedAction();
}
void QDragDrop::dragMoveEvent(QDragMoveEvent *event)
{
__super::dragMoveEvent(event);
if (event->mimeData()->hasFormat("MyImage"))
event->acceptProposedAction();
}
void QDragDrop::dropEvent(QDropEvent *event)
{
__super::dropEvent(event);
if (event->mimeData()->hasFormat("MyImage"))
{
QByteArray byteArray = event->mimeData()->data("MyImage");//取数据
QDataStream stream(&byteArray, QIODevice::ReadOnly);//流,读数据
QImage image;
stream >> image;
QLabel *pLabel = new QLabel(this);
pLabel->setPixmap(QPixmap::fromImage(image));
m_HBox->addWidget(pLabel);
}
}
如果我们只需要接收放下,不需要拖动的话,那么就不需要上述示例中的两个鼠标事件。下面实现了一个拖动图片到窗口并使用QLabel显示出来的示例:
效果:
示例代码:
#ifndef QSHOWIMAGE_H #define QSHOWIMAGE_H #include <QWidget> #include <QHBoxLayout> #include <QDragEnterEvent> #include <QMimeData> class QShowImage : public QWidget { Q_OBJECT public: QShowImage(QWidget *parent = 0); ~QShowImage(); protected: void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); private: QHBoxLayout *mLayout; }; #endif // QSHOWIMAGE_H
#include "QShowImage.h" #include <QLabel> #include <QDebug> QShowImage::QShowImage(QWidget *parent) : QWidget(parent) { mLayout = new QHBoxLayout(this); setAcceptDrops(true); setWindowTitle("ShowImage"); } QShowImage::~QShowImage() { } void QShowImage::dragEnterEvent(QDragEnterEvent *event) { __super::dragEnterEvent(event); if (event->mimeData()->hasUrls()) event->acceptProposedAction(); } void QShowImage::dropEvent(QDropEvent *event) { __super::dropEvent(event); if (event->mimeData()->hasUrls()) { QList<QUrl> urls = event->mimeData()->urls(); for each (QUrl url in urls) { QLabel *pLabel = new QLabel(this); QImage image(url.toString().mid(8)); pLabel->setPixmap(QPixmap::fromImage(image)); mLayout->addWidget(pLabel); } } }
对于QListWidget来说,拖放并不像上面那样复杂,仅仅设置一下,就可以实现QListWidgetItem的拖动:
setDragEnabled(true);
实现代码:
QListWidget qlistWidget; QStringList strList = { "Item1", "Item2", "Item3", "Item4", "Item5" }; qlistWidget.addItems(strList); qlistWidget.setViewMode(QListView::IconMode); qlistWidget.setDragEnabled(true); qlistWidget.show();但是上述只是移动了位置,Item的具体索引并没有发生改变。而且如果我们需要实现其他拖放功能,并不能满足我们的需求。那么我们就需要重新实现拖放事件,来自定义我们自己需要实现的功能。我实现了如何拖动Item,然后再添加一个Item的功能,两个QListWidgetItem并没有什么关联,只是为了展示如何实现。
效果:
示例代码:
#ifndef LISTWIDGET_H #define LISTWIDGET_H #include <QListWidget> #include <QMouseEvent> class ListWidget : public QListWidget { Q_OBJECT public: ListWidget(QWidget *parent = 0); ~ListWidget(); void dragEnterEvent(QDragEnterEvent *event); void dragMoveEvent(QDragMoveEvent *event); void dropEvent(QDropEvent *event); private: }; #endif // LISTWIDGET_H
#include "ListWidget.h" #include <QDrag> #include <QMimeData> #include <QLabel> ListWidget::ListWidget(QWidget *parent) : QListWidget(parent) { QStringList strList = { "Item1", "Item2", "Item3", "Item4", "Item5" }; addItems(strList); setViewMode(QListView::IconMode); setDragEnabled(true); setWindowTitle("QListWidget"); } ListWidget::~ListWidget() { } void ListWidget::dragEnterEvent(QDragEnterEvent *event) { __super::dragEnterEvent(event); ListWidget *pList = qobject_cast<ListWidget *>(event->source());//拖动的源对象 if (pList && pList == this) { event->setDropAction(Qt::DropAction::CopyAction);//设置拖动动作,影响鼠标光标 event->accept(); } } void ListWidget::dragMoveEvent(QDragMoveEvent *event) { __super::dragMoveEvent(event); ListWidget *pList = qobject_cast<ListWidget *>(event->source());//拖动的源对象 if (pList && pList == this) { event->setDropAction(Qt::DropAction::CopyAction);//设置拖动动作,影响鼠标光标 event->accept(); } } void ListWidget::dropEvent(QDropEvent *event) { __super::dropEvent(event); ListWidget *pList = qobject_cast<ListWidget *>(event->source());//拖动的源对象 if (pList && pList == this) { QListWidgetItem *pItem = new QListWidgetItem(this);//执行释放后,要做的事情 pItem->setText(QString("Item").append(QString::number(count()))); addItem(pItem); } }
交流QQ:1245178753
本文地址:http://blog.csdn.net/u011417605/article/details/51316037
源码下载:http://download.csdn.net/detail/u011417605/9509997
相关文章推荐
- pyqt4,QTableWidget 动态添加控件,添加图片,右键菜单选项
- 关于QT的正则表达式类QRegExp的细节问题
- qt源码 以及 如何查看源码
- PCL1.8+Qt5+VS2013可视化点云
- 获取谷歌地图的API KEY
- mqtt 推送的客户端测试方法
- Qt 窗体的模态与非模态
- 在HI3531上移植和运行QT4.8.6
- Qt使用中的小问题
- Qt之二维绘图
- [Q学习]4 QT的元对象系统
- 什么是qt,QT Creator, QT SDK, QT Designer
- Qt中的QString,QByteArray,Qchar, char*
- Qt开发笔记
- Qt多线程笔记 (2)
- Qt开发之信号槽机制
- Qt多线程笔记 (1)
- Qt5 模块简介
- PyQt5教程——对话框(6)
- Qt5-MSVC2012-qDebug中文乱码解决方法