qt 可拖拽treeWidget

QMyTreeWidget.h
#pragma once

#include <QTreeWidget>
#include <QInputDialog>
#include <QAction>
#include <QMenu>
#include <QUuid>
#include <QPushButton>
#include <QCheckBox>
#include <QLabel>
#include <QTreeWidgetItem>
#include <QMouseEvent>
#include <QDataStream>
#include <QDrag>
#include <QMimeData>

class QMyTreeWidget : public QTreeWidget
{
    Q_OBJECT

public:
    QMyTreeWidget(QWidget *parent=0);
    ~QMyTreeWidget();
    static QString treeWidgetItemMimeType() { return QStringLiteral("data/itemPtr"); }
private:
    void initWidget();
    QTreeWidgetItem *currentItem;

    //空白地方点击
    QAction *addRootNodeAction;
    QAction *deleteAllNodesAction;

    //节点上点击
    QAction *addCategoryAction;
    QAction *addTemplateAction;
    QAction *deleteNodeAction;
    QAction *reNameNodeAction;

    QLabel* label;
    QTreeWidgetItem* _selectItem;
    QTreeWidgetItem* _selectItem2;

protected:
    void dragEnterEvent(QDragEnterEvent *event) override;
    void dropEvent(QDropEvent *event) override;
    void startDrag(Qt::DropActions supportedActions) override;
    void dragLeaveEvent(QDragLeaveEvent *event) override;
    void dragMoveEvent(QDragMoveEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
private slots:
    void on_treeWidget_customContextMenuRequested(const QPoint &pos);
    void addRootNode();
    void deleteAllNodes();
    void addCategory();
    void addTemplate();
    void deleteNode();
    void reNameNode();

};
QMyTreeWidget.cpp
#include "QMyTreeWidget.h"
#include <QDebug>

QMyTreeWidget::QMyTreeWidget(QWidget *parent)
    : QTreeWidget(parent)
{
    initWidget();
    label = new QLabel();
}

QMyTreeWidget::~QMyTreeWidget()
{
}
void QMyTreeWidget::initWidget()
{
    addRootNodeAction = new QAction("&addRootNode", this);
    deleteAllNodesAction = new QAction("&deleteAllNodes", this);

    addCategoryAction = new QAction("&addCategory", this);
    addTemplateAction = new QAction("&addTemplate", this);

    deleteNodeAction = new QAction("&deleteNode", this);
    reNameNodeAction = new QAction("&reNameNode", this);

    connect(addRootNodeAction, SIGNAL(triggered()), this, SLOT(addRootNode()));
    connect(deleteAllNodesAction, SIGNAL(triggered()), this, SLOT(deleteAllNodes()));

    connect(addCategoryAction, SIGNAL(triggered()), this, SLOT(addCategory()));
    connect(addTemplateAction, SIGNAL(triggered()), this, SLOT(addTemplate()));

    connect(deleteNodeAction, SIGNAL(triggered()), this, SLOT(deleteNode()));
    connect(reNameNodeAction, SIGNAL(triggered()), this, SLOT(reNameNode()));

    this->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(this, SIGNAL(customContextMenuRequested(QPoint)),
        this, SLOT(on_treeWidget_customContextMenuRequested(QPoint)));

    this->setHeaderHidden(false);
    QStringList list;
    list << QStringLiteral("列表") << QStringLiteral("是否为子节点");
    this->setHeaderLabels(list);

    this->setSelectionMode(QAbstractItemView::ExtendedSelection);
    this->setDragEnabled(true);
    this->setAcceptDrops(true);
    this->setDefaultDropAction(Qt::MoveAction);
    //this->setDragDropMode(QAbstractItemView::DragDrop);
    this->setDragDropMode(QAbstractItemView::InternalMove);
}

void QMyTreeWidget::on_treeWidget_customContextMenuRequested(const QPoint &pos)
{
    currentItem = this->itemAt(pos);

    if (currentItem == NULL) {
        QMenu *popMenu = new QMenu(this);
        popMenu->addAction(addRootNodeAction);
        popMenu->addAction(deleteAllNodesAction);
        popMenu->exec(QCursor::pos());
    }
    else {
        QMenu *popMenu = new QMenu(this);//定义一个右键弹出菜单
        popMenu->addAction(addCategoryAction);
        popMenu->addAction(addTemplateAction);
        popMenu->addAction(deleteNodeAction);
        popMenu->addAction(reNameNodeAction);
        popMenu->exec(QCursor::pos());
    }
}

//鼠标按下执行操作(ok)
void QMyTreeWidget::mousePressEvent(QMouseEvent * event)
{
    if(event->button()==Qt::LeftButton){
        QTreeWidgetItem *selectedItem = static_cast<QTreeWidgetItem*>(this->itemAt(event->pos()));
        currentItem = selectedItem;
        if(selectedItem!=NULL){


            QByteArray data;
            QDataStream dataStream(&data, QIODevice::WriteOnly);
            unsigned long long selectedItemPtr = (unsigned long long)(selectedItem);
            dataStream << selectedItemPtr;

            QMimeData *mimeData = new QMimeData;
            mimeData->setData(QMyTreeWidget::treeWidgetItemMimeType(), data);

            label->setText(QString::number(selectedItemPtr));
            label->adjustSize();

            QDrag *drag = new QDrag(this);
            drag->setMimeData(mimeData);
            drag->setHotSpot(QPoint(label->grab().width() / 2, label->grab().height() / 2));
            drag->setPixmap(label->grab());

            Qt::DropAction dropAction = drag->exec(Qt::MoveAction|Qt::CopyAction,Qt::MoveAction);
            qDebug()<<dropAction;
            if (dropAction == Qt::MoveAction || dropAction == Qt::CopyAction) {
                delete currentItem;
                currentItem = NULL;
                //selectedItem->parent()->removeChild(selectedItem);
                qDebug()<<"delete";
            }
        }
    }
    QTreeWidget::mousePressEvent(event);
}
//鼠标拖动操作(ok)
void QMyTreeWidget::dragMoveEvent(QDragMoveEvent * event)
{
    if (event->mimeData()->hasFormat(QMyTreeWidget::treeWidgetItemMimeType())) {
        event->setDropAction(Qt::MoveAction);
        event->accept();
    } else {
        event->ignore();
    }
}
//鼠标移入操作(ok)
void QMyTreeWidget::dragEnterEvent(QDragEnterEvent * event)
{
    if (event->mimeData()->hasFormat(QMyTreeWidget::treeWidgetItemMimeType())){
        if (event->source() == this) {
            if (children().contains(event->source())) {
                event->setDropAction(Qt::MoveAction);
                event->accept();
            }
            else {
                event->acceptProposedAction();
            }
        }
        else {
            event->acceptProposedAction();
        }
    }
    else
        event->ignore();
}
//鼠标放下操作
void QMyTreeWidget::dropEvent(QDropEvent * event)
{
    if (event->mimeData()->hasFormat(QMyTreeWidget::treeWidgetItemMimeType())){

        QByteArray data = event->mimeData()->data(QMyTreeWidget::treeWidgetItemMimeType());
        QDataStream dataStream(&data,QIODevice::ReadOnly);
        unsigned long long treeItemPtr;
        dataStream >> treeItemPtr;
        QTreeWidgetItem *twItem = reinterpret_cast<QTreeWidgetItem*>(treeItemPtr);

        QTreeWidgetItem *selectedItem = static_cast<QTreeWidgetItem*>(this->itemAt(event->pos()));
        if(twItem == currentItem){
            return;
        }
        qDebug()<<(unsigned long long)twItem;
        qDebug()<<(unsigned long long)selectedItem;
        if(selectedItem == 0x0){
            QTreeWidgetItem *item;
            item = twItem->clone();
            //item->setText(0,twItem->text(0));
            this->addTopLevelItem(item);
            //twItem->setExpanded(true);
        }else{
            QTreeWidgetItem *item;
            item = twItem->clone();
            //item->setText(0,twItem->text(0));
            selectedItem->addChild(item);
        }

        if (event->source() == this) {
            event->setDropAction(Qt::MoveAction);
            event->accept();
        }
        else {
            event->acceptProposedAction();
        }
    }else{
        event->ignore();
    }
}
//鼠标开始拖拽
void QMyTreeWidget::startDrag(Qt::DropActions supportedActions)
{

}
//鼠标移出操作
void QMyTreeWidget::dragLeaveEvent(QDragLeaveEvent * event)
{
    event->accept();
}

void QMyTreeWidget::addRootNode()
{
    QTreeWidgetItem *temp = new QTreeWidgetItem();
    QInputDialog dia(this);
    dia.setWindowTitle("Input Dialog");
    dia.setLabelText("Please input text:");
    dia.setInputMode(QInputDialog::TextInput);

    if (dia.exec() == QInputDialog::Accepted)
    {
        this->addTopLevelItem(temp);
        temp->setText(0, dia.textValue());
        this->setItemWidget(temp, 1, new QCheckBox());
        QVariant var;
        QString str = QUuid::createUuid().toString();
        var.setValue(str);
        temp->setData(0, Qt::UserRole, var);
    }
}

void QMyTreeWidget::deleteAllNodes()
{
    this->clear();
}

void QMyTreeWidget::addCategory()
{
    QTreeWidgetItem *temp = new QTreeWidgetItem(currentItem);

    QInputDialog dia(this);
    dia.setWindowTitle("Input Dialog");
    dia.setLabelText("Please input text:");
    dia.setInputMode(QInputDialog::TextInput);//可选参数:DoubleInput  TextInput

    if (dia.exec() == QInputDialog::Accepted)
    {
        temp->setText(0, dia.textValue());
        this->setItemWidget(temp, 1, new QCheckBox());
        //        temp->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
        //        temp->setCheckState(0, Qt::Unchecked);
        QVariant var;
        QString str = QUuid::createUuid().toString();
        var.setValue(str);
        temp->setData(0, Qt::UserRole, var);
    }
}

void QMyTreeWidget::addTemplate()
{
    QTreeWidgetItem *temp = new QTreeWidgetItem(currentItem);

    QInputDialog dia(this);
    dia.setWindowTitle("Input Dialog");
    dia.setLabelText("Please input text:");
    dia.setInputMode(QInputDialog::TextInput);

    if (dia.exec() == QInputDialog::Accepted)
    {
        temp->setText(0, dia.textValue());
        QVariant var;
        QString str = QUuid::createUuid().toString();
        var.setValue(str);
        temp->setData(0, Qt::UserRole, var);
    }
}

void QMyTreeWidget::deleteNode()
{
    QTreeWidgetItem* parent = currentItem->parent();
    if (parent == NULL)
    {
        //得到索引
        int index = 0;
        int count = this->topLevelItemCount();
        for (int i = 0; i < count; i++)
        {
            //QTreeWidget
            //ui->treeWidget->TopLevelItem()
            QTreeWidgetItem* temp = this->topLevelItem(i);
            if (currentItem->data(0, Qt::UserRole).toString() == temp->data(0, Qt::UserRole).toString())
            {
                index = i;
            }
        }
        this->takeTopLevelItem(index);
    }
    else
        parent->removeChild(currentItem);
}

void QMyTreeWidget::reNameNode()
{
    QInputDialog dia(this);
    dia.setWindowTitle("Input Dialog");
    dia.setLabelText("Please input text:");
    dia.setInputMode(QInputDialog::TextInput);//可选参数:DoubleInput  TextInput

    if (dia.exec() == QInputDialog::Accepted)
    {
        currentItem->setText(0, dia.textValue());
    }
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值