Qt:QTreeWidget拖拽item到QGraphicsScene

简述:

简单的实现了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()
{
    delete ui;
}

代码参照了网上一个博主的代码,但是找不到链接了。



转载于:https://www.jianshu.com/p/7edf17810425

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值