QTreeWidget实现节点拖拽

前言

刚进公司没多久,老大就让做一个实现拖放的小插件,要求可拖拽,可缩放。从网上查了很多资料,也看了别人写的demo,总算摸索出一些门道,界面布局有些丑,希望大家不要介意,下面分享给大家,如有疑问,可评论,大家一起学习!

效果

在这里插入图片描述

核心代码

QCTreeWidget.cpp

// 左侧项目树
QCTreeWidget::QCTreeWidget(const QString& text, QWidget *parent)
: QTreeWidget(parent)
{
    this->setSelectionMode(QAbstractItemView::ExtendedSelection);
    this->setDragEnabled(true);
    this->setAcceptDrops(true);
    this->setDefaultDropAction(Qt::MoveAction);
    //this->setDragDropMode(QAbstractItemView::DragDrop);
    this->setDragDropMode(QAbstractItemView::InternalMove);
}

void QCTreeWidget::mousePressEvent(QMouseEvent *e)
{
    QTreeWidgetItem *item = currentItem();
    if (item == NULL)
        return;

    QString pValue = QString::number(int((void*)item));
    QByteArray itemData;
    itemData = QVariant(pValue).toByteArray();

    QMimeData *mimeData = new QMimeData;
    mimeData->setData("application/x-qabstractitemmodeldatalist", itemData);

    QDrag *drag = new QDrag(this);
    drag->setMimeData(mimeData);

    hide();

    Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction);

    if (dropAction == Qt::MoveAction)
        close();
    else
        show();
}

void QCTreeWidget::dragEnterEvent(QDragEnterEvent *event)
{
    QWidget *source =  qobject_cast<QCTreeWidget *>(event->source());
    if (source /*&& source != this*/)
    {
        event->setDropAction(Qt::MoveAction);
        /*event->setDropAction(Qt::MoveAction);  */
        event->accept();
    }
}

void QCTreeWidget::dragMoveEvent(QDragMoveEvent *event)
{
    QWidget *source =  qobject_cast<QCTreeWidget *>(event->source());
    if (source /*&& source != this*/)
    {
        event->setDropAction(Qt::MoveAction);
        event->accept();
    }
}

void QCTreeWidget::dropEvent(QDropEvent *event)
{
    QCTreeWidget *source =  qobject_cast<QCTreeWidget *>(event->source());
    if (source /*&& source != this*/)
    {
        QCTreeWidget *source = qobject_cast<QCTreeWidget *>(event->source());
        if(source)
        {
            QTreeWidgetItem *item = this->itemAt(event->pos()); //当前位置的item
            if( item == nullptr)   //如果放下的位置没有item,则退出,没有这句话死机!
                return;
			//如果“放下位置的item是顶层item,且原来的是顶层”或者“放下的不是顶层,且原来也不是顶层”
            if( -1 == this->indexOfTopLevelItem(item) && (-1 == this->indexOfTopLevelItem(currentItem())) ||
                    -1 != this->indexOfTopLevelItem(item) && (-1 != this->indexOfTopLevelItem(currentItem())))
 
            {
                qDebug()<< QStringLiteral("放下的文本是: ")<<event->mimeData()->text();
                item->setText(currentColumn(),event->mimeData()->text());
                event->setDropAction(Qt::MoveAction);
                event->accept();
            }
        }
    }
}

void QCTreeWidget::startDrag(Qt::DropActions /*supportedActions*/)
{
    QMimeData *mimeData = new QMimeData;
    mimeData->setText("fasfas");
    QDrag *drag = new QDrag((QWidget*)(this));
    drag->setMimeData(mimeData);
    drag->exec(Qt::MoveAction);//注意这里一定要是MoveAction
}

void QCTreeWidget::mouseMoveEvent(QMouseEvent *e)
{
    if(e->buttons() & Qt::LeftButton)
    {
     
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kevin_org

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值