通过treewidget的拖放实现组管理功能(启用拖放功能的时候判定接收拖放的treewidgetitem是否为顶层节点)

我实现的效果如下图所示:
qtreewidget控件本来就能实现拖放功能,但由于默认的功能是任意节点都能拖放后成为其他节点的子节点,和我的需求有点差距。
我的需求是能tree只有2列,第一列为组,第二列为组内成员。
拖放的时候,只能把组内成员拖动到任意组内,但不能成为成员的成员。
因此我继承了一个qtreewidget,源码如下:

在这里插入图片描述
mainwindow.h

#include <QMainWindow>
#include <QTreeWidgetItem>
#include "mytreewidget.h"
namespace Ui {
    
    
class MainWindow;
}
class MainWindow : public QMainWindow
{
    
    
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    MyTreeWidget *m_MyTreeWidget;
private:
    Ui::MainWindow *ui;
};

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#pragma execution_character_set("utf-8")//让能够正常显示中文字符串
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    
    
    ui->setupUi(this);
    m_MyTreeWidget = new MyTreeWidget(this);
    ui->vboxLayout->addWidget(m_MyTreeWidget);

    m_MyTreeWidget->setColumnCount(1);//设置列数
    m_MyTreeWidget->setColumnWidth(0,200);//设置列宽
    m_MyTreeWidget->setHeaderHidden(true);//隐藏标题栏
    m_MyTreeWidget->setDragEnabled(true);//启动拖放
    m_MyTreeWidget->setAcceptDrops(true);//接收拖放
    m_MyTreeWidget->setDropIndicatorShown(true);//设置显示将要被放置的位置
    m_MyTreeWidget->setDragDropMode(QAbstractItemView::InternalMove);//设置拖放模式为移动项目,否则为复制项目
    QTreeWidgetItem *imageItem1 = new QTreeWidgetItem(m_MyTreeWidget,QStringList(QString("图像1")));
    //imageItem1->setIcon(0,QIcon(":/down"));
    QTreeWidgetItem *imageItem1_1 = new QTreeWidgetItem(imageItem1,QStringList(QString("Band1")));//子节点1
    imageItem1->addChild(imageItem1_1);
    QTreeWidgetItem *imageItem2 = new QTreeWidgetItem(m_MyTreeWidget,QStringList(QString("图像2")));
    //imageItem2->setIcon(0,QIcon(":/down"));
    QTreeWidgetItem *imageItem2_1 = new QTreeWidgetItem(imageItem2,QStringList(QString("Band2")));//子节点2
    QTreeWidgetItem *imageItem2_2 = new QTreeWidgetItem(imageItem2,QStringList(QString("Band3")));//子节点2
    imageItem2->addChild(imageItem2_1);
    imageItem2->addChild(imageItem2_2);
}

MainWindow::~MainWindow()
{
    
    
    delete ui;
}

自己写的继承自qtreewidget的类MyTreeWidget.h

#include <QWidget>
#include <QTreeWidget>
#include <QPainter>
#include <QMimeData>
#include <QDrag>
#include <QMouseEvent>
#include <QDebug>

class MyTreeWidget:public QTreeWidget
{
    
    
    Q_OBJECT
public:
    MyTreeWidget(QWidget *parent);
    ~MyTreeWidget();
    void dropEvent(QDropEvent *event);
};

MyTreeWidget.cpp

#include "mytreewidget.h"

MyTreeWidget::MyTreeWidget(QWidget *parent):QTreeWidget(parent)
{
    
    
    this->setSelectionMode(QAbstractItemView::ExtendedSelection);//正常为单选,但按下ctrl后可以是多选
    this->setDragEnabled(true);//设置可拖动
    this->setAcceptDrops(true);//设置接收拖放
    this->viewport()->setAcceptDrops(true);
    this->setDropIndicatorShown(true);//设置显示要被放置的位置
    this->setDragDropMode(QAbstractItemView::DragDrop);//设置拖放模式为移动项目,否则为复制项目
    this->setDefaultDropAction(Qt::MoveAction);
}

MyTreeWidget::~MyTreeWidget()
{
    
    

}

void MyTreeWidget::dropEvent(QDropEvent *event)
{
    
    
    MyTreeWidget *source = qobject_cast<MyTreeWidget *>(event->source());
    if(source)
    {
    
    
        QTreeWidgetItem *item = this->itemAt(event->pos()); //当前位置的item
        if( item == nullptr)   //如果放下的位置没有item,则退出,没有这句话死机!
            return;
        QTreeWidgetItem  *pItem = item->parent();
        if(pItem != nullptr)//放下位置的item不是父节点
        {
    
    
            return;
        }
    }
    QTreeView::dropEvent(event);//没有这句话会导致拖放不成功!
}

猜你喜欢

转载自blog.csdn.net/weixin_43935474/article/details/105940657