Drag & drop in a QTableView: which flags do I need in the model?
-
@robert-hairgrove said in Drag & drop in a QTableView: which flags do I need in the model?:
So in the model class, presumably I should NOT set the flag Qt::ItemIsEditable but only Qt::ItemIsDropEnabled, is this correct?
yes
I also need to ensure that only items from the same row can be dropped into other columns. I assume that I would need to derive a custom class from QAbstractTableView and overload the dragEnterEvent() in order to record which row this was called upon?
better
QAbstractItemModel::canDropMimeData()
That looks good for the destination. How does he know what the source row/column was? That has nothing to do with MIME type.
-
better
QAbstractItemModel::canDropMimeData()
That looks good for the destination. How does he know what the source row/column was? That has nothing to do with MIME type.
@jonb said in Drag & drop in a QTableView: which flags do I need in the model?:
How does he know what the source row/column was?
either reimplement a custom mimeData() method or decode the data yourself (which might not be the best idea since the encoding might change in future Qt versions)
-
@jonb said in Drag & drop in a QTableView: which flags do I need in the model?:
How does he know what the source row/column was?
either reimplement a custom mimeData() method or decode the data yourself (which might not be the best idea since the encoding might change in future Qt versions)
@raven-worx
(Bearing in mind I've never actually done any of this)
I'm lost with the MIME data stuff, conceptually. What OP seems to want is to use a drag operation in the view to cause the model to copy data from oneQModelIndex
to another. To me there shouldn't be any "data to decode"? I just want to know theQModelIndex
es of the start and end of the drag-drop? -
@raven-worx
(Bearing in mind I've never actually done any of this)
I'm lost with the MIME data stuff, conceptually. What OP seems to want is to use a drag operation in the view to cause the model to copy data from oneQModelIndex
to another. To me there shouldn't be any "data to decode"? I just want to know theQModelIndex
es of the start and end of the drag-drop?@jonb said in Drag & drop in a QTableView: which flags do I need in the model?:
To me there shouldn't be any "data to decode"?
either use the data which is already provided (as it is encoded into a bytestream) or add custom data when you want custom behavior. The data can contain anything you like and can easily added.
This needs to be done anyway, no matter where the drop is handled. -
@jonb said in Drag & drop in a QTableView: which flags do I need in the model?:
To me there shouldn't be any "data to decode"?
either use the data which is already provided (as it is encoded into a bytestream) or add custom data when you want custom behavior. The data can contain anything you like and can easily added.
This needs to be done anyway, no matter where the drop is handled.@raven-worx
OK. I read up. In https://doc.qt.io/qt-5/qmimedata.html#detailsIf the drag and drop operation occurs within a single application, we can subclass QMimeData and add extra data in it, and use a qobject_cast() in the receiver's drop event handler. For example:
void MyWidget::dropEvent(QDropEvent *event) { const MyMimeData *myData = qobject_cast<const MyMimeData *>(event->mimeData()); if (myData) { // access myData's data directly (not through QMimeData's API) } }
So this is how OP will pass information about the
QModelIndex
of the source, and be able to check its row against the destination's, right? -
@raven-worx
OK. I read up. In https://doc.qt.io/qt-5/qmimedata.html#detailsIf the drag and drop operation occurs within a single application, we can subclass QMimeData and add extra data in it, and use a qobject_cast() in the receiver's drop event handler. For example:
void MyWidget::dropEvent(QDropEvent *event) { const MyMimeData *myData = qobject_cast<const MyMimeData *>(event->mimeData()); if (myData) { // access myData's data directly (not through QMimeData's API) } }
So this is how OP will pass information about the
QModelIndex
of the source, and be able to check its row against the destination's, right?@jonb
no, no need to subclass QMimeData.
QMimeData can hold arbitrary data already. So a custom mime-type can be used for example.mimeData->setData("my/data", data)
-
@raven-worx : Thank you for the suggestion to use a custom MIME type. I also never did this but once, many years ago, but with a much simpler use case.
If I understand correctly, in addition to my own model class, I will need to subclass
QTableView
(since there is noQAbstractTableView
, but onlyQAbstractTableModel
) and re-implement thestartDrag()
function? That seems to be the only place where I can set the MIME data. Then I can let the model handle everything else, I guess.One more question: Can I use multiple MIME types, calling
QMimeData::setData()
for each type? This seems to be the easiest to implement. Otherwise, I would probably encode it in JSON format. -
Actually, I see now that it is the function
QAbstractItemModel::mimeData()
that has to be re-implemented because the default implementation ofQAbstractItemView::startDrag()
calls this function for each item (i.e. QModelIndex) which is selected for dragging.So there is no need for a custom view ... the model handles everything itself?
-
Actually, I see now that it is the function
QAbstractItemModel::mimeData()
that has to be re-implemented because the default implementation ofQAbstractItemView::startDrag()
calls this function for each item (i.e. QModelIndex) which is selected for dragging.So there is no need for a custom view ... the model handles everything itself?
@robert-hairgrove said in Drag & drop in a QTableView: which flags do I need in the model?:
the model handles everything itself?
yes
-
@robert-hairgrove said in Drag & drop in a QTableView: which flags do I need in the model?:
the model handles everything itself?
yes
@raven-worx : Thanks very much!