[Qt-interest] QTreeWidget - Dragging and Dropping to move items
David Ching
dc at dcsoft.com
Sat May 16 17:18:14 CEST 2009
Hello, I have started with http://www.qtsoftware.com/developer/faqs/588 of a
QTreeWidget which allows dragging and dropping. But I want to drag and drop
to MOVE top-level items within the tree, to change their order. It works.
The mimeData() function returns a QMimeData with the index of the source
item, and the dropMimeData() receives the item that was dropped on:
QMimeData *QDDTreeWidget::mimeData(const QList<QTreeWidgetItem *> items)
const
{
// Create a QByteArray to store the data for the drag.
QByteArray ba;
// Create a data stream that operates on the binary data
QDataStream ds(&ba, QIODevice::WriteOnly);
ds << indexOfTopLevelItem(items.at(0));
QMimeData *md = new QMimeData;
// Set the data associated with the mime type foo/bar to ba
md->setData("foo/bar", ba);
return md;
}
bool QDDTreeWidget::dropMimeData(QTreeWidgetItem *parent, int index, const
QMimeData *data,
Qt::DropAction action)
{
if (parent) {
// Create a QByteArray from the mimedata associated with
foo/bar
QByteArray ba = data->data("foo/bar");
// Create a data stream that operates on the binary data
QDataStream ds(&ba, QIODevice::ReadOnly);
if (!ds.atEnd())
{
int sourceIndex;
// Read a byte from the stream into the string
ds >> sourceIndex;
QTreeWidgetItem *movedItem = topLevelItem
(sourceIndex); // remove it from old position
emit itemMoved(movedItem, parent); // <-- My
new signal; parent is item that was dropped on to
}
}
return true;
}
The problem is that the code receiving the itemMoved() signal always inserts
the movedItem on top of the 'parent' item, so even if I drop onto the bottom
item in the tree, it is inserted above it. There is no way to insert in the
bottom-most position of the tree.
Other drag and drop schemes show a thin horizontal line between the items
and the item is dropped onto the horizontal line. The line can appear below
the bottommost item or above the topmost item. Is there a Qt QTreeWidget
that does this?
Another scheme would be to, when the drag is started, insert a dummy item at
the bottom of the tree so the user can drop on that to insert at the bottom.
Then remove the dummy item when the drop is complete. I've experimented
with that but had issues with autoscrolling sometimes not showing the new
dummy item. But perhaps this would be easier to get working?
Anyway, this dragging and dropping to re-order is a pretty common thing to
do, so I suspect someone has already solved this issue.
Thanks,
David
More information about the Qt-interest-old
mailing list