PDA

View Full Version : whole row drag/drop



gyre
26th November 2007, 21:06
hi guys...
How can I set the model so it would take the whole row when dragging it ?
I can set the selection behaviour to be select rows...but how can I set that the actual selected row would be dragged ?
Or is it possible ? Or the only possibility is to use a selection model ?
Thanks

jpn
26th November 2007, 21:33
Hmm, according to my test the whole row IS dragged out of the box when selection behavior is "select rows"...

gyre
26th November 2007, 21:47
Well yes...but I dont know how should I serialize them...


QMimeData* QVcaMsgSeqModel::mimeData(const QModelIndexList &indexes) const
{
QMimeData *mimeData = new QMimeData();
QByteArray encodedData;

QTextStream stream(&encodedData, QIODevice::WriteOnly);

foreach (QModelIndex index, indexes) {
if (index.isValid()) {
QString text = data(index, Qt::DisplayRole).toString();
stream << text;
}
}

mimeData->setData("application/message", encodedData);
return mimeData;
}


I have 4 columns in each of my rows...now I have to serialize them so I could then decode them from the model...but if you consider that indexes in that "foreach cycle" doesnt neccessary mean that each column will be following each in one row than I dont know how to decode the data ...I got now into a dead point :(

jpn
26th November 2007, 21:53
Did you try without reimplementing mimeData() and dropMimeData()? Just make itemData() return all the required roles in case you need to embed custom data.

gyre
26th November 2007, 21:55
no I havent...but shouldnt I reimplement those two methods to enable drag and drop ??

jpn
26th November 2007, 21:56
no I havent...but shouldnt I reimplement those two methods to enable drag and drop ??
Not necessarily, the default implementation in QAbstractItemModel is surprisingly good. ;)

gyre
26th November 2007, 23:30
wel...but I have to reimplement drag/drop mouse events hm ?
its not working somwhow without them...
but maybe my codes are wrong :(

jpn
26th November 2007, 23:50
wel...but I have to reimplement drag/drop mouse events hm ?
No, you don't reimplement them either. Model's mimeData() and dropMimeData() will get called by the framework when appropriate. However, the default implementation of those is sufficient, you don't need to reimplement them either.

First of all, make sure to drop all of these

QVcaMsgSeqModel::mimeData()
QVcaMsgSeqModel::dropMimeData()
QVcaMsgSeqModel::mimeTypes()


Secondly, define a custom role to handle can messages. For example:


enum
{
QVcaCanMsgRole = Qt::UserRole
};


Then, reimplement itemData() as already advised:


QMap<int, QVariant> QVcaMsgSeqModel::itemData(const QModelIndex &index) const
{
QMap<int, QVariant> roles = QAbstractTableModel::itemData(index);
// add additional custom data
roles.insert(QVcaCanMsgRole, QVariant::fromValue(msgList.at(index.row())));
return roles;
}


Now, make setData() handle the custom role and you're all set:


bool QVcaMsgSeqModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
...
if (index.isValid() && role == QVcaCanMsgRole)
{
msgList[row] = value.value<QVcaCanMsg>();
}
...
}


Notice that QVcaCanMsg must be declared to Qt's meta system to be able to use it with QVariant:

Q_DECLARE_METATYPE(QVcaCanMsg);

wysota
27th November 2007, 00:02
Hmmm... what's the QVcaCanMsgRole meta type for? As far as I know you declare metatypes for classes and the role is... a number.

jpn
27th November 2007, 00:21
Hmmm... what's the QVcaCanMsgRole meta type for? As far as I know you declare metatypes for classes and the role is... a number.
Good notice! I meant QVcaCanMsg, of course. :)

gyre
27th November 2007, 00:40
Well this code works ...
EXCEPT...every dragged row is dropped 3 times :(( PLUS it is added at hte end of the TableView :(....dunno why :((...

And another question...Is there any way how to FORBID drag and drop in actual widget...
I mean...I dont want drop to be performed in inside the widget Im draggind items from...

Thanks...

wysota
27th November 2007, 02:46
You can always check if the source of the drag is the same as the current widget. As for forbidding all drops, there is "acceptDrops" property in QWidget.

gyre
27th November 2007, 06:32
so I made it work...except for one little thing...that the items are not droped at the actual position but still at the end ...

jpn
27th November 2007, 09:56
May I ask, why do you insist of rewriting error prone mimeData() and dropMimeData() if QAbstractItemModel/QAbstractTableModel already implements them for you? Just take a look at src/corelib/kernel/qabstractitemmodel.cpp if you don't believe me. ;) All the data returned by itemData() is packed to MIME data by default so you can simply embed your CAN messages to those. As a proof of concept, I have attached an example which does not reimplement mimeData() nor dropMimeData().