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);
}
相关推荐
吴声子夜歌几秒前
Guava——反射
java·开发语言·guava
lingran__6 分钟前
Git 完全指南(三):远程仓库与标签管理
开发语言·git·gitee·ssh·团队协作·远程仓库·分布式版本控制
for_ever_love__8 分钟前
python爬虫: 数据解析
开发语言·爬虫·python·xpath
学习星球16 分钟前
AI 一句话生成 3D 游戏世界:腾讯 HY-World 2.0 开源深度解析与本地实战
开发语言·人工智能·游戏·3d·ai·课程设计·ai编程
名字还没想好☜18 分钟前
Go 用 -race 抓数据竞争:一个偶发崩溃的排查、原理与修复
开发语言·后端·golang·go
励志不掉头发的内向程序员20 分钟前
LibreCAD 2D架构】从鼠标点击到屏幕像素:LibreCAD绘图架构全链路解析之鼠标事件与RS_ActionDrawLine
c++·qt·学习·架构·计算机外设
小灰灰搞电子30 分钟前
Rust std::vec::Vec<T>动态数组:所有相关 API 全面介绍
开发语言·rust
学习星球32 分钟前
CodeWhale 深度剖析:从 DeepSeek-TUI 到 40.9K Star 的 Rust 终端编程 Agent
开发语言·后端·rust
行云&流水35 分钟前
自动备份mysql数据库
数据库·mysql
IMPYLH1 小时前
HTML 的 <option> 元素
服务器·数据库·html