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);
}
相关推荐
行者964 分钟前
Flutter适配OpenHarmony:国际化i18n实现中的常见陷阱与解决方案
开发语言·javascript·flutter·harmonyos·鸿蒙
csbysj20206 分钟前
RSS 阅读器:全面解析与使用指南
开发语言
溪海莘13 分钟前
如何部署使用uv管理依赖的python项目 ?
开发语言·python·uv
我送炭你添花15 分钟前
Python与串口:从基础到实际应用——以Pelco KBD300A模拟器项目为例
开发语言·python·自动化·运维开发
No0d1es15 分钟前
2025年12月 GESP CCF编程能力等级认证C++八级真题
开发语言·c++·青少年编程·gesp·ccf
晴天¥34 分钟前
Oracle如何在DBeaver上进行登录
数据库·oracle
hqwest34 分钟前
码上通QT实战10--监控页面02-绘制温度盘
开发语言·qt·自定义控件·qwidget·提升部件·qt绘图
m0_6265352042 分钟前
快速排序学习 l方法 h方法
开发语言·python
2301_800256111 小时前
事务处理-同步与调度-两阶段锁-隔离级别
数据库·oracle
小罗和阿泽1 小时前
MySql数据库系列 数据库基础操作
数据库·mysql