PDA

View Full Version : Drag 'n Drop QListWidget: no text while dragging if not default drag used



trallallero
10th June 2010, 12:56
I have a little problem with DnD using a QListWidget.
I have to create my own QListWidget class (called CListWidget) as I need to implement my own mousePressEvent method.


void CListWidget::mousePressEvent(QMouseEvent *event)
{
QListWidget::mousePressEvent(event);

if ( currentItem()->text().isEmpty() )
{
clearSelection();
return;
}

QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << currentItem()->text();

QMimeData *mimeData = new QMimeData;
mimeData->setData("application/x-dnditemdata", itemData);
mimeData->setText(currentItem()->text());

QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->exec(Qt::CopyAction);
}

When using this code, I cannot see any text while dragging.
If I comment the code and just enable the drag:


CListWidget::CListWidget(QWidget* parent) : QListWidget(parent)
{
setDragEnabled(true);
}

the text of the CListWidget item is shown while dragging.

Why ?

The problem is also that, if I use the QT default drag, I don't have any text in the item dragged.

Thanks for any suggestion :)


PS: Using Qt version 4.4.0 under Linux Ubuntu 8.04

aamer4yu
10th June 2010, 13:27
You will need to set pixmap in mime data to see the text while dragging...
From the docs -

void QAbstractItemView::startDrag(Qt::DropActions supportedActions)
{
Q_D(QAbstractItemView);
QModelIndexList indexes = d->selectedDraggableIndexes();
if (indexes.count() > 0) {
QMimeData *data = d->model->mimeData(indexes);
if (!data)
return;
QRect rect;
QPixmap pixmap = d->renderToPixmap(indexes, &rect); // HERE THEY RENDER TEXT TO PIXMAP
rect.adjust(horizontalOffset(), verticalOffset(), 0, 0);
QDrag *drag = new QDrag(this);
drag->setPixmap(pixmap); // THE PIXMAP FOR SHOWING TEXT
drag->setMimeData(data);
drag->setHotSpot(d->pressedPosition - rect.topLeft());
Qt::DropAction defaultDropAction = Qt::IgnoreAction;
if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction))
defaultDropAction = d->defaultDropAction;
else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
defaultDropAction = Qt::CopyAction;
if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction)
d->clearOrRemove();
}
}

trallallero
10th June 2010, 13:47
Thanks but I don't follow you...
I guess I have to reimplement the virtual method startDrag in my CListWidget class, but I get errors.

trallallero
10th June 2010, 15:13
Well, I've solved in this way:

added the following to the constructor:



QPen pen(QColor("blue"));
m_Pixmap = new QPixmap(QSize(180, 20));
m_Painter = new QPainter(m_Pixmap);
m_Painter->setPen(pen);


and the mousePressEvent is now:



void CListWidget::mousePressEvent(QMouseEvent *event)
{
QListWidget::mousePressEvent(event);

if ( currentItem()->text().isEmpty() )
{
clearSelection();
return;
}

QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << currentItem()->text();

m_Painter->fillRect(QRect(0, 0, 180, 20), QBrush(QColor("orange"))); // ADDED
m_Painter->drawText(QRect(10, 0, 170, 20), currentItem()->text() ); // ADDED

QMimeData *mimeData = new QMimeData;
mimeData->setData("application/x-dnditemdata", itemData);
mimeData->setText(currentItem()->text());

QDrag *drag = new QDrag(this);
drag->setPixmap(*m_Pixmap); // ADDED
drag->setMimeData(mimeData);
drag->exec(Qt::CopyAction);
}