Qt实现控件拖曳

DragTreeWidget.h

#ifndef DRAGTREEWIDGET_H
#define DRAGTREEWIDGET_H

#include <QTreeWidget>

class QMouseEvent;

class DragTreeWidget : public QTreeWidget
{
    Q_OBJECT
public:
    DragTreeWidget(QWidget *parent = nullptr);

private:
    void init();

protected:
    virtual void mousePressEvent(QMouseEvent *event) override;
};

#endif // DRAGTREEWIDGET_H

DragTreeWidget.cpp

#include "DragTreeWidget.h"
#include <QMouseEvent>
#include <QMimeData>
#include <QDrag>
#include "QtGuiDrag.h"
#include <QDebug>



DragTreeWidget::DragTreeWidget(QWidget *parent)
    : QTreeWidget(parent)
{
    //初始化数据
    (void)init();

    //设置拖曳模式
    (void)setDragDropMode(QAbstractItemView::InternalMove);

    //使能拖曳
    (void)setDragEnabled(true);
}

void DragTreeWidget::init()
{
    QTreeWidgetItem* topItemSource = new QTreeWidgetItem(this);
    topItemSource->setText(0, QStringLiteral("信号源"));
//    topItemSource->setIcon()
    QTreeWidgetItem* topItemSourceFun1 = new QTreeWidgetItem(topItemSource);
    topItemSourceFun1->setText(0, QStringLiteral("连接设备"));
    QTreeWidgetItem* topItemSourceFun2 = new QTreeWidgetItem(topItemSource);
    topItemSourceFun2->setText(0, QStringLiteral("设置频率"));
    QTreeWidgetItem* topItemSourceFun3 = new QTreeWidgetItem(topItemSource);
    topItemSourceFun3->setText(0, QStringLiteral("设置功率"));
    topItemSource->setExpanded(true);

    QTreeWidgetItem* topItemSpectrum = new QTreeWidgetItem(this);
    topItemSpectrum->setText(0, QStringLiteral("频谱仪"));
    QTreeWidgetItem* topItemSpectrumFun1 = new QTreeWidgetItem(topItemSpectrum);
    topItemSpectrumFun1->setText(0, QStringLiteral("连接设备"));
    QTreeWidgetItem* topItemSpectrumFun2 = new QTreeWidgetItem(topItemSpectrum);
    topItemSpectrumFun2->setText(0, QStringLiteral("设置频率"));
    QTreeWidgetItem* topItemSpectrumFun3 = new QTreeWidgetItem(topItemSpectrum);
    topItemSpectrumFun3->setText(0, QStringLiteral("设置功率"));
    QTreeWidgetItem* topItemSpectrumFun4 = new QTreeWidgetItem(topItemSpectrum);
    topItemSpectrumFun4->setText(0, QStringLiteral("设置衰减"));
    topItemSpectrum->setExpanded(true);

    QTreeWidgetItem* topItemVna = new QTreeWidgetItem(this);
    topItemVna->setText(0, QStringLiteral("矢网"));
    QTreeWidgetItem* topItemVnaFun1 = new QTreeWidgetItem(topItemVna);
    topItemVnaFun1->setText(0, QStringLiteral("连接设备"));
    QTreeWidgetItem* topItemVnaFun2 = new QTreeWidgetItem(topItemVna);
    topItemVnaFun2->setText(0, QStringLiteral("设置频率"));
    QTreeWidgetItem* topItemVnaFun3 = new QTreeWidgetItem(topItemVna);
    topItemVnaFun3->setText(0, QStringLiteral("设置功率"));
    topItemVna->setExpanded(true);
}

void DragTreeWidget::mousePressEvent(QMouseEvent *event)
{

    if(event->button() & Qt::LeftButton)
    {
        qDebug()<<"mousePressEvent 1";

        QTreeWidgetItem *child = static_cast<QTreeWidgetItem*>(itemAt(event->pos()));    //获取当前点击的item对象
        if(!child)
        {
            return;
        }
        QByteArray dataItem;
        QDataStream dataStream(&dataItem, QIODevice::WriteOnly);
        dataStream << child->text(0);
        QMimeData* mimeData = new QMimeData;
        mimeData->setData("Data/name", dataItem);

        QtGuiDrag* dragPixmap = new QtGuiDrag(nullptr);
        dragPixmap->setShowText(child->text(0));
        QPixmap pixmap = dragPixmap->grab();

        QDrag *drag = new QDrag(this);                                  //创建一个拖曳对象并存储相关信息
        drag->setMimeData(mimeData);
        drag->setPixmap(pixmap);
        drag->setHotSpot(QPoint(pixmap.width()/2, pixmap.height()/2));
        qDebug()<<"mousePressEvent 2";
        drag->exec(Qt::MoveAction);
        qDebug()<<"mousePressEvent 3";
    }
    QTreeWidget::mouseMoveEvent(event);
}

DragWidget.h

#ifndef DRAGWIDGET_H
#define DRAGWIDGET_H

#include <QFrame>

class QDragEnterEvent;
class QDropEvent;

class DragWidget : public QFrame
{
public:
    explicit DragWidget(QWidget *parent = nullptr);

protected:
    void dragEnterEvent(QDragEnterEvent *event) override;
    void dropEvent(QDropEvent *event) override;
};

#endif // DRAGWIDGET_H

DragWidget.cpp

#include "DragWidget.h"
#include <QDragEnterEvent>
#include <QMimeData>
#include <QLabel>
#include <QDebug>


DragWidget::DragWidget(QWidget *parent)
    : QFrame(parent)
{
    setFrameStyle(QFrame::Sunken | QFrame::StyledPanel);
    setAcceptDrops(true);
}

void DragWidget::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasFormat("Data/name"))
    {
        if (event->source() == this)
        {
            event->setDropAction(Qt::MoveAction);
            event->accept();
        }
        else
        {
            event->acceptProposedAction();
        }
    }
    else
    {
        event->ignore();
    }
}

void DragWidget::dropEvent(QDropEvent *event)
{
    qDebug()<<"dropEvent";
    if (event->mimeData()->hasFormat("Data/name"))
    {
        QByteArray itemData = event->mimeData()->data("Data/name");
        QDataStream dataStream(&itemData, QIODevice::ReadOnly);

        QString txt;
        dataStream >> txt;

        QLabel *newIcon = new QLabel(this);
        newIcon->setText(txt);

        //计算位置
        newIcon->move(event->pos()/* - offset*/);
        newIcon->show();
        newIcon->setAttribute(Qt::WA_DeleteOnClose);

        if (event->source() == this)
        {
            event->setDropAction(Qt::MoveAction);
            event->accept();
        }
        else
        {
            event->acceptProposedAction();
        }
    }
    else
    {
        event->ignore();
    }
}

QtGuiDrag.h

#ifndef QTGUIDRAG_H
#define QTGUIDRAG_H

#include <QWidget>

namespace Ui {
class QtGuiDrag;
}

class QtGuiDrag : public QWidget
{
    Q_OBJECT

public:
    explicit QtGuiDrag(QWidget *parent = nullptr);
    ~QtGuiDrag();

    void setShowText(const QString& txt);
private:
    Ui::QtGuiDrag *ui;
};

#endif // QTGUIDRAG_H

QtGuiDrag.cpp

#include "QtGuiDrag.h"
#include "ui_QtGuiDrag.h"

QtGuiDrag::QtGuiDrag(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::QtGuiDrag)
{
    ui->setupUi(this);
    this->setWindowFlags(Qt::FramelessWindowHint);
    this->setAttribute(Qt::WA_TranslucentBackground, true);
}

QtGuiDrag::~QtGuiDrag()
{
    delete ui;
}

void QtGuiDrag::setShowText(const QString &txt)
{
    ui->label->setText(txt);
}
相关推荐
尚雷55801 分钟前
Oracle 与 达梦 数据库 对比
数据库·oracle·达梦数据库
VBA63372 分钟前
VBA高级应用30例应用在Excel中的ListObject对象:向表中添加注释
开发语言
Dontla3 分钟前
Rust字节数组(Byte Array)Rust u8、Vec<u8>、数组切片、向量切片、字符串转字节数组转字符串、&[u8]类型:字节数组引用
开发语言·rust
小猿姐1 小时前
Ape-DTS:开源 DTS 工具,助力自建 MySQL、PostgreSQL 迁移上云
数据库·mysql·postgresql·开源
百香果果ccc2 小时前
MySQL中的单行函数和聚合函数
数据库·mysql
摸摸陌陌2 小时前
Redis快速入门
数据库·redis·缓存
走在考研路上2 小时前
Python错误处理
开发语言·python
数据小爬虫@2 小时前
Python爬虫:如何优雅地“偷窥”商品详情
开发语言·爬虫·python
CV大法好2 小时前
刘铁猛p3 C# 控制台程序引用System.Windows.Forms报错,无法引用程序集 解决方法
开发语言·c#
Days20502 小时前
uniapp小程序增加加载功能
开发语言·前端·javascript