简述:
简单的实现了QTreeWidget 拖拽图形 到QGraphicsScene的演示效果。
拖拽的实现,一般需要四个函数
//鼠标压下事件,启动拖拽事件
void mousePressEvent(QMouseEvent* event) override;
//drag操作在窗体移动事件
void dragMoveEvent(QDragMoveEvent* event) override;
//drag操作进入窗体
void dragEnterEvent(QDragEnterEvent* event) override;
//drop释放事件
void dropEvent(QDropEvent* event) override;
中间有很多坑,其实是文档没看明白。
我代码简单实现自定义qtreewidget 点击 启动拖拽一个MimeData,MimeData可以添加很多类型数据,我这里拖拽一个label用于显示。拖拽到了GraphicsView 里再次传递给自定义的GraphicsScene 接收。
自定义场景类MyScene里 开启拖拽接收权限,当鼠标释放,接收传递的数据。
#ifndef MYSCENE_H
#define MYSCENE_H
#include <QGraphicsScene>
#include <QGraphicsSceneEvent>
#include <QGraphicsSceneDragDropEvent>
#include <QMimeData>
#include <QGraphicsRectItem>
#include <QObject>
#include <QDrag>
class MyScene:public QGraphicsScene
Q_OBJECT
public:
MyScene(QObject *parent = nullptr);
protected:
//drag操作在窗体移动事件
void dragMoveEvent(QGraphicsSceneDragDropEvent *event) override;
//drag操作进入窗体
void dragEnterEvent(QGraphicsSceneDragDropEvent* event) ;
//drop释放事件
void dropEvent(QGraphicsSceneDragDropEvent* event) ;
#endif // MYSCENE_H
#include "MyScene.h"
#include <QDebug>
MyScene::MyScene(QObject *parent):QGraphicsScene(parent)
void MyScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
//坑1 并不是在DragEnterEvent 开启接受权限 而是在这
event->accept();
//event->setAccepted(true);
//不能调用父类的,会把权限关闭
// QGraphicsScene::dragMoveEvent(event);
void MyScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
event->accept();
//event->setAccepted(true);
QGraphicsScene::dragEnterEvent(event);
void MyScene::dropEvent(QGraphicsSceneDragDropEvent *event)
if (event->mimeData()->hasFormat("Data/name"))
//获取拖拽的数据
QByteArray itemData = event->mimeData()->data("Data/name");
QDataStream dataStream(&itemData, QIODevice::ReadOnly);
QString text;
dataStream >>text;
qDebug()<<text;
//创建一个item
QGraphicsRectItem * item = new QGraphicsRectItem();
//坑2 event->pos() 失效了 坐标一直是(0,0),直接用场景坐标
item->setRect(event->scenePos().x(),event->scenePos().y(),100,50);
this->addItem(item);
QGraphicsScene::dropEvent(event);
自定义QTreeWidget 类
#include "MyScene.h"
#include <QDebug>
MyScene::MyScene(QObject *parent):QGraphicsScene(parent)
void MyScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
//坑1 并不是在DragEnterEvent 开启接受权限 而是在这
event->accept();
//event->setAccepted(true);
//不能调用父类的,会把权限关闭
// QGraphicsScene::dragMoveEvent(event);
void MyScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
event->accept();
//event->setAccepted(true);
QGraphicsScene::dragEnterEvent(event);
void MyScene::dropEvent(QGraphicsSceneDragDropEvent *event)
if (event->mimeData()->hasFormat("Data/name"))
//获取拖拽的数据
QByteArray itemData = event->mimeData()->data("Data/name");
QDataStream dataStream(&itemData, QIODevice::ReadOnly);
QString text;
dataStream >>text;
qDebug()<<text;
//创建一个item
QGraphicsRectItem * item = new QGraphicsRectItem();
//坑2 event->pos() 失效了 坐标一直是(0,0),直接用场景坐标
item->setRect(event->scenePos().x(),event->scenePos().y(),100,50);
this->addItem(item);
QGraphicsScene::dropEvent(event);
#include "MyTree.h"
#include <QMimeData>
MyTree::MyTree(QWidget *parent):QTreeWidget(parent)
void MyTree::init()
//设置树形头部控件
setHeaderLabel(tr("节点拖动Demo"));
//创建树形
//父节点1
QTreeWidgetItem* pTree1 = new QTreeWidgetItem(this);
pTree1->setText(0,QStringLiteral("父节点1"));
//子节点
QTreeWidgetItem* sTree1_1 = new QTreeWidgetItem(pTree1);
sTree1_1->setText(0,QStringLiteral("子节点1"));
QTreeWidgetItem* sTree1_2 = new QTreeWidgetItem(pTree1);
sTree1_2->setText(0,QStringLiteral("子节点2"));
pTree1->setExpanded(true);
m_label = new QLabel(this);
m_label->resize(100,50);
m_label->hide();
void MyTree::mousePressEvent(QMouseEvent *event)
m_selectItem = static_cast<QTreeWidgetItem*>(this->itemAt(event->pos()));
if (event->button()==Qt::LeftButton&&m_selectItem){
QByteArray dataItem;
QDataStream dataStream(&dataItem, QIODevice::WriteOnly);
dataStream << m_selectItem->text(0);
m_label->setText(m_selectItem->text(0));
//设置自定义数据
QMimeData* mimeData = new QMimeData;
mimeData->setData("Data/name", dataItem);
//拖动设置
QDrag* drag = new QDrag(this);
drag->setPixmap(m_label->grab());
drag->setMimeData(mimeData);
drag->setHotSpot(QPoint(0,0));
drag->exec();
// Qt::DropAction dropAction = drag->exec(Qt::MoveAction|Qt::CopyAction,Qt::CopyAction);
// if(dropAction == Qt::MoveAction)
// {
// //当成功拖动时清除原节点
// delete m_selectItem;
// m_selectItem = NULL;
// qDebug()<<"成功";
// }
QTreeWidget::mousePressEvent(event);
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "MyTree.h"
#include "MyScene.h"
#include <QGraphicsView>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
MyTree * mytree;
MyScene * myscene;
QGraphicsView * view;
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include <QRectF>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
ui->setupUi(this);
resize(500,500);
mytree = new MyTree(this);
mytree->setGeometry(0,0,180,500);
mytree->init();
myscene = new MyScene;
myscene->setSceneRect(QRect(0,0,300,500));
view = new QGraphicsView(this);
//view->setAcceptDrops(true);
view ->setGeometry(200,0,300,500);
view->setScene(myscene);
Widget::~Widget()