我实现的效果如下图所示:
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);//没有这句话会导致拖放不成功!
}