PDA

View Full Version : Enable Drag & Drop between QTableWidget and QLineEdit



Infinity
31st March 2013, 21:16
Hi

I have a QTableWidget and I want to enable Drag & Drop functionality. For that I'm using the following code:



tableWidget->setDragEnabled(true);
tableWidget->setDragDropOverwriteMode(true);
tableWidget->setDragDropMode(QAbstractItemView::DragDrop);
tableWidget->setDefaultDropAction(Qt::CopyAction);


The Drag & Drop functionality works, but only between other QTableWidgets. It doesn't work between a QTableWidget and a QLineEdit. Is it possible to enable Drag & Drop between QTableWidgets and QLineEdits, too?
Has someone an idea to solve the problem?

EDIT: I already tried overwriting dropEvent, dragMoveEvent and dragEnterEvent. I'm not sure what to do, but simply calling event->acceptProposedAction(); or calling event->accept(); doesn't work.

If I use the following code and try do drop some text from any text field (e. g. the address bar in my browser) my application terminates (segmentation fault).


void DragAndDropTableWidget::dragEnterEvent(QDragEnterE vent *event)
{
event->acceptProposedAction();
}


(I'm using the Linux Version of Qt 5.0.1)

giblit
1st April 2013, 02:33
Prob because your trying to drop an item into a line edit try drooping the item->text()

Infinity
1st April 2013, 18:58
I'm not sure what you mean. Can you explain this a bit more detailed. But I'm not trying to drop data into a line edit - I'm trying to drop data from the line edit into a cell. (Both is not working, but the program terminates only in this case.)



void DragAndDropTableWidget::dropEvent(QDropEvent *event)
{
QTableWidget::dropEvent(event);
}

void DragAndDropTableWidget::dragMoveEvent(QDragMoveEve nt *event)
{
QTableWidget::dragMoveEvent(event);
}

void DragAndDropTableWidget::dragEnterEvent(QDragEnterE vent *event)
{
QTableWidget::dragEnterEvent(event);
}

bool DragAndDropTableWidget::dropMimeData(int row, int column, const QMimeData *data, Qt::DropAction action)
{
return QTableWidget::dropMimeData(row, column, data, action);
}

I set in each method a break point to check out if or when these functions are getting called. These functions only get called when I drag & drop between QTableWidgets so I think nothing can be achieved by overwriting these methods.

This is likely not related to my problem but I also noticed that Spotify (which also uses Qt, at least the Linux version) terminates if you try to drag & drop songs.

Infinity
3rd April 2013, 17:40
I think I found a solution to the problem.

The QTableWidget uses a special MIME type which can't be used by other controls/applications but there is a way to add additional MIME types by overwriting the following methods:



bool DragAndDropTableWidget::dropMimeData(int row, int column, const QMimeData *data, Qt::DropAction action)
{
if(data->hasText())
{
QTableWidgetItem *item = this->item(row, column);
if(item != 0)
item->setText(data->text());
return false;
}
else
{
return QTableWidget::dropMimeData(row, column, data, action);
}
}

QStringList DragAndDropTableWidget::mimeTypes() const
{
return QTableWidget::mimeTypes() << QStringLiteral("text/plain");
}

QMimeData *DragAndDropTableWidget::mimeData(const QList<QTableWidgetItem *> items) const
{
QString text;
if(items.count() > 0)
{
QTableWidgetItem *lastItem = items.last();
foreach(QTableWidgetItem *item, items)
{
if(!item->text().isEmpty())
{
text.append(item->text());
if(item != lastItem)
{
text.append(QStringLiteral("\n"));
}
}
}
}
QMimeData *data = QTableWidget::mimeData(items);
data->setText(text);

return data;
}

I'm adding the MIME type "text/plain" which is used by most applications and it seems to work (even if there are multiple cells selected).
There's no use in overwriting dropEvent, dragMoveEvent and dragEnterEvent.

If someone has suggestions to improve the code, let me know because I'm not sure how to deal with that methods due I found no examples about them and the documentation doesn't give a lot of information, too.