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);
}
相关推荐
q***d1731 分钟前
Rust并发模型
开发语言·后端·rust
CircleMouse6 分钟前
介绍几个axios接口请求顺序的问题
开发语言·前端·javascript·ecmascript
cipher11 分钟前
删库之夜·Ω诡计
数据库·程序员
好记忆不如烂笔头abc15 分钟前
DBMS_RESOURCE_MANAGER.CALIBRATE_IO测试oracle的iops和延迟
数据库·oracle
HitpointNetSuite19 分钟前
生物医药企业ERP系统比较:为什么选择Oracle NetSuite?
数据库·oracle·netsuite·erp·hitpointcloud
baivfhpwxf202322 分钟前
用TCP服务端向多个客户端分发图片,客户端接收并处理图片,再将处理结果返回给服务端
服务器·开发语言·网络·tcp/ip·c#
资深web全栈开发23 分钟前
Golang Cobra 教程:构建强大的CLI应用
开发语言·后端·golang
好记忆不如烂笔头abc25 分钟前
Oracle ORION模拟Database负载测试存储性能
数据库·oracle
xdpcxq102931 分钟前
使用.NET 8+ 与飞书API构建同步服务
数据库·.net·飞书
J***793932 分钟前
Python在机器学习中的数据处理
开发语言·python·机器学习