Seite 1 von 1

Drag & Drop auf Model

Verfasst: 12. Oktober 2012 17:50
von Alf79
Hallo,

ich habe eine Frage zu Drag & Drop mit Modellen. Normales Drag & Drop mit Überschreiben der Methoden usw. funktioniert einwandfrei, nur bei Modellen will es mir nicht so recht gelingen. Das Problem ist, ich Drage(!?) von einem eigenen QListWidget auf das TableView, der Drop-Event kommt im TableView::dropEvent(...) an, jedoch nicht im TableModel::dropMimeData(...). Habe ich da was falsch verstanden oder vergessen einzubauen? Wenn mir da bitte jemand einen Hinweis geben könnte woran es liegt. Danke!

Ich habe hier mein abgeleitetes QTableView:

TableView.h

Code: Alles auswählen

#ifndef TABLEVIEW_H
#define TABLEVIEW_H

#include <QTableView>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>

class TableView : public QTableView
{
		Q_OBJECT
	public:
		explicit TableView(QWidget *parent = 0);

		void dragEnterEvent(QDragEnterEvent *event);
		void dragMoveEvent(QDragMoveEvent *event);
		void dropEvent(QDropEvent *event);
};

#endif // TABLEVIEW_H
TableView.cpp

Code: Alles auswählen

#include "tableview.h"

namespace
{
	const QString MIME_DATA_ID = "application/x-qt-table-drag-data-mime";
}

TableView::TableView(QWidget *parent) : QTableView(parent)
{
}

void TableView::dragEnterEvent(QDragEnterEvent *event)
{
	if(event->mimeData()->hasFormat(::MIME_DATA_ID))
		event->accept();
	else
		event->ignore();
}

void TableView::dragMoveEvent(QDragMoveEvent *event)
{
	if(event->mimeData()->hasFormat(::MIME_DATA_ID))
		event->accept();
	else
		event->ignore();
}

void TableView::dropEvent(QDropEvent *event)
{
	if(event->mimeData()->hasFormat(::MIME_DATA_ID))
		event->accept();
	else
		event->ignore();
}
Und dann habe habe ich noch mein abgeleitetes Model:

TableModel.h

Code: Alles auswählen

#ifndef TABLEMODEL_H
#define TABLEMODEL_H

#include <QAbstractTableModel>
#include <QModelIndex>
#include <QStringList>

class QMimeData;

class TableModel : public QAbstractTableModel
{
		Q_OBJECT
	public:
		explicit TableModel(QObject *parent = 0);

		int rowCount(const QModelIndex &parent) const;
		int columnCount(const QModelIndex &parent) const;

		QVariant data(const QModelIndex &index, int role) const;
		QVariant headerData(int section, Qt::Orientation orientation, int role) const;
		QMimeData *mimeData(const QModelIndexList &indexes) const;
		Qt::ItemFlags flags(const QModelIndex &index) const;
		Qt::DropActions supportedDropActions() const;
		Qt::DropActions supportedDragActions() const;

		bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
		bool setData(const QModelIndex &index, const QVariant &value, int role);

		bool insertRows(int row, int count, const QModelIndex &parent);
		bool removeRows(int row, int count, const QModelIndex &parent);
		
	private:
		QStringList p_data_list;
};

#endif // TABLEMODEL_H
TableModel.cpp

Code: Alles auswählen

#include "tablemodel.h"
#include <QMimeData>

namespace
{
	const QString MIME_DATA_ID = "application/x-qt-table-drag-data-mime";
}

TableModel::TableModel(QObject *parent) : QAbstractTableModel(parent)
{
}

int TableModel::rowCount(const QModelIndex &parent) const
{
	return p_data_list.size();
}

int TableModel::columnCount(const QModelIndex &parent) const
{
	return 2;
}

QVariant TableModel::data(const QModelIndex &index, int role) const
{
	if(!index.isValid() || index.row() <= p_data_list.size())
		return QVariant();

	if(role == Qt::DisplayRole)
	{
		switch(index.column())
		{
			case 0:
				return p_data_list.at(index.row());
			default:
				return QVariant();
		}
	}

	return QVariant();
}

QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
	if(role == Qt::DisplayRole && orientation == Qt::Horizontal)
	{
		switch(section)
		{
			case 0:
				return "objectName";
			case 1 :
				return "objectText";
		}
	}

	return QVariant();
}

QMimeData *TableModel::mimeData(const QModelIndexList &indexes) const
{
	return 0;
}

Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
{
	return QAbstractTableModel::flags(index) | Qt::ItemIsDropEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}

Qt::DropActions TableModel::supportedDropActions() const
{
	return Qt::CopyAction | Qt::MoveAction;
}

Qt::DropActions TableModel::supportedDragActions() const
{
	return Qt::CopyAction | Qt::MoveAction;
}

bool TableModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
	Q_UNUSED(column)

	if(!data->hasFormat(MIME_DATA_ID))
		return false;

	if(action == Qt::IgnoreAction)
		return true;

	QByteArray encoded = data->data(::MIME_DATA_ID);
	QDataStream stream(&encoded, QIODevice::ReadOnly);

	while(!stream.atEnd())
	{
		QString text_data;
		stream >> text_data;

		p_data_list.insert(row, text_data);
	}

	return true;
}

bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
	return true;
}

bool TableModel::insertRows(int row, int count, const QModelIndex &parent)
{
	beginInsertRows(QModelIndex(), row, row+count);
	endInsertRows();

	return true;
}

bool TableModel::removeRows(int row, int count, const QModelIndex &parent)
{
	beginRemoveRows(QModelIndex(), row, row+count);;
	endRemoveRows();

	return true;
}
MainWindow.h

Code: Alles auswählen

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "listwidget.h"
#include "tableview.h"
#include "tablemodel.h"

namespace Ui {
	class MainWindow;
}

class MainWindow : public QMainWindow
{
		Q_OBJECT
		
	public:
		explicit MainWindow(QWidget *parent = 0);
		~MainWindow();
		
	private:
		Ui::MainWindow *ui;
		TableView *my_table;
		TableModel *my_model;
		ListWidget *my_list;
};

#endif // MAINWINDOW_H
MainWindow.cpp

Code: Alles auswählen

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
	QMainWindow(parent),
	ui(new Ui::MainWindow)
{
	ui->setupUi(this);

	my_list = new ListWidget(this);
	my_list->setDragEnabled(true);

	my_model = new TableModel(this);

	my_table = new TableView(this);
	my_table->setModel(my_model);
	my_table->setAcceptDrops(true);
	my_table->setDropIndicatorShown(true);
	my_table->setSelectionMode(QAbstractItemView::ExtendedSelection);

	ui->ListWidgetPanel->layout()->addWidget(my_list);
	ui->TableViewPanel->layout()->addWidget(my_table);

	QListWidgetItem *itm = new QListWidgetItem("Test",my_list);
}

MainWindow::~MainWindow()
{
	delete ui;
}
Danke und Grüße,
Alfred

Re: Drag & Drop auf Model

Verfasst: 15. Oktober 2012 09:06
von archer
Da du das dropEvent() überschreibst, wirst du dropMimeData() selber aufrufen müssen.
Oder bei dir in der Methode bei accept, QTableView::dropEvent() aufrufen.