Solved crash in QListWidget::dropEvent when I add a UserRole to my QListItemWidget :'(
-
@VRonin said in crash in QListWidget::dropEvent when I add a UserRole to my QListItemWidget :'(:
My fault, I totally forgot you also need qRegisterMetaTypeStreamOperators
Ok, now I don't have the "QVariant::save: unable to save type 'Element*' (type id: 1025).
" message but the app is crashing in an infinite loop in:inline QDataStream &operator>>(QDataStream &in, Element*& elem) { in >> elem; return in; }
on the first line...
Thread 1 (Thread 0x7ffff7fb8140 (LWP 16621)): #0 0x000055555557fd65 in operator>> (in=..., elem=@0x7fffffffa280: 0x0) at ../src_cosi7/Model/Element.h:370 No locals. #1 0x000055555557fd6a in operator>> (in=..., elem=@0x7fffffffa280: 0x0) at ../src_cosi7/Model/Element.h:370 No locals. #2 0x000055555557fd6a in operator>> (in=..., elem=@0x7fffffffa280: 0x0) at ../src_cosi7/Model/Element.h:370 No locals. #3 0x000055555557fd6a in operator>> (in=..., elem=@0x7fffffffa280: 0x0) at ../src_cosi7/Model/Element.h:370 No locals. #4 0x000055555557fd6a in operator>> (in=..., elem=@0x7fffffffa280: 0x0) at ../src_cosi7/Model/Element.h:370 No locals. #5 0x000055555557fd6a in operator>> (in=..., elem=@0x7fffffffa280: 0x0) at ../src_cosi7/Model/Element.h:370 No locals. #6 0x000055555557fd6a in operator>> (in=..., elem=@0x7fffffffa280: 0x0) at ../src_cosi7/Model/Element.h:370 No locals. #7 0x000055555557fd6a in operator>> (in=..., elem=@0x7fffffffa280: 0x0) at ../src_cosi7/Model/Element.h:370 No locals. #8 0x000055555557fd6a in operator>> (in=..., elem=@0x7fffffffa280: 0x0) at ../src_cosi7/Model/Element.h:370 ... #261515 0x000055555557fd6a in operator>> (in=..., elem=@0x7fffffffa280: 0x0) at ../src_cosi7/Model/Element.h:370 No locals. #261516 0x000055555557fd6a in operator>> (in=..., elem=@0x7fffffffa280: 0x0) at ../src_cosi7/Model/Element.h:370 No locals. #261517 0x0000555555580182 in QtMetaTypePrivate::QMetaTypeFunctionHelper<Element*, true>::Load (stream=..., t=0x7fffffffa280) at /opt/Qt/5.10.1/gcc_64/include/QtCore/qmetatype.h:777 No locals. #261518 0x00007ffff66c596a in QMetaType::load(QDataStream&, int, void*) () from /opt/Qt/5.10.1/gcc_64/lib/libQt5Core.so.5 No symbol table info available. #261519 0x00007ffff66ed12c in QVariant::load(QDataStream&) () from /opt/Qt/5.10.1/gcc_64/lib/libQt5Core.so.5 No symbol table info available. #261520 0x00007ffff66ed25f in operator>>(QDataStream&, QVariant&) () from /opt/Qt/5.10.1/gcc_64/lib/libQt5Core.so.5 No symbol table info available. #261521 0x00005555555ef34e in QtPrivate::readAssociativeContainer<QMap<int, QVariant> > (s=..., c=...) at /opt/Qt/5.10.1/gcc_64/include/QtCore/qdatastream.h:285 k = 256 t = {d = {data = {c = 0 '\000', uc = 0 '\000', s = 0, sc = 0 '\000', us = 0, i = 0, u = 0, l = 0, ul = 0, b = false, d = 0, f = 0, real = 0, ll = 0, ull = 0, o = 0x0, ptr = 0x0, shared = 0x0}, type = 1025, is_shared = 0, is_null = 0}} i = 0 stateSaver = {stream = 0x7fffffffa310, oldStatus = QDataStream::Ok} n = 3 #261522 0x00005555555eebff in operator>><int, QVariant> (s=..., map=...) at /opt/Qt/5.10.1/gcc_64/include/QtCore/qdatastream.h:436 No locals. #261523 0x00005555555ed678 in ItemOfferingListWidget::dropEvent (this=0x5555562138d0, event=0x7fffffffa8f0) at ../src_cosi7/hmi/GUI/widget/ItemOfferingListWidget.cpp:103 userRoleIter = {i = 0x7fffffffa480} mimeData = {d = 0x5555563d7f70} modelData = {d = 0x7ffff67e4940 <QMapDataBase::shared_null>} mimeReader = {d = {d = 0x5555563a35c0}, dev = 0x55555617f260, owndev = true, noswap = false, byteorder = QDataStream::BigEndian, ver = 17, q_status = QDataStream::Ok} row = 0 col = 0 __PRETTY_FUNCTION__ = "virtual void ItemOfferingListWidget::dropEvent(QDropEvent*)" #261524 0x00007ffff7735018 in QWidget::event(QEvent*) () from /opt/Qt/5.10.1/gcc_64/lib/libQt5Widgets.so.5 No symbol table info available.
-
That's because your code is an obvious infinite recursion. You have to fix it
-
Yes, there're something wrong with the >> operator.
Anyway, I think it's a oversized process just to save a single pointer ...
QDataStream allows to save/load a pointer to char:
operator<<(const char *s) operator>>(char *&s)
So, you simply need to use reinterpret_cast, back and forth for your custom class.
Et voilà -
Well I nearly lost a day on this so I think I'm just going to stay with my working version where I create my own QDrag and put by hand the reinterpret_cast of the address of my pointer.
It works well and I don't need the register and registerforstream of my metatype (neither to reimplement the stream operator on DataStream) -
@mpergand said in crash in QListWidget::dropEvent when I add a UserRole to my QListItemWidget :'(:
Yes, there're something wrong with the >> operator.
Anyway, I think it's a oversized process just to save a single pointer ...
QDataStream allows to save/load a pointer to char:
operator<<(const char *s) operator>>(char *&s)
So, you simply need to use reinterpret_cast, back and forth for your custom class.
Et voilàYep that is what I'm doing but through a qulonglong instead of the char*
That's because your code is an obvious infinite recursion. You have to fix it
I pasted your code from the other post thinking the break would end the for loop. (I don't know the transaction objects you're using)
I've updated to be:const QByteArray mimeData = event->mimeData()->data("application/x-qabstractitemmodeldatalist"); QDataStream mimeReader(mimeData); int row, col; QMap<int,QVariant> modelData; while (!mimeReader.atEnd()) { mimeReader >> row >> col >> modelData; qDebug() << "Receiving row: " << row << " modelData.size: " << modelData.size(); const auto userRoleIter = modelData.constFind(Qt::UserRole); if(userRoleIter != modelData.cend()) { Element *elem = userRoleIter->value<Element*>(); qDebug() << "Receiving elem: " << elem->getName() << " (row in original list: " << row << ")"; } else{ qDebug() << "No UserRole..."; } }
but I still have the same issue...
I don't see the obvious recursive loop :(
this code is working well if I don't use the Qmap<int, QVariant> but build the QDrag myself.
Could you let me know what's wrong plz -
@mbruel said in crash in QListWidget::dropEvent when I add a UserRole to my QListItemWidget :'(:
I don't see the obvious recursive loop
inside
inline QDataStream &operator>>(QDataStream &in, Element*& elem) { in >> elem; return in; }
in >> elem;
callsQDataStream &operator>>(QDataStream &in, Element*& elem)
. that's the infinite recursion.Serialising pointers to objects as numerics tickles my evil detector, in any case, Qt has
qintptr
type that is designed for this -
@VRonin
ah yeah indeed... I've just copied the code without thinking cause without it and only the add of the qRegisterMetaTypeStreamOperators it wasn't working so I guess I need to reimplement the stream operator on DataStream .anyway, if I've to do that, and cast the pointer address, I don't see the point of doing all this. I'm just gonna cast directly in the dragStart in my own QDrag and decode it like I was doing in my working solution above.
Thanks for the qintptr, I'm going to use this instead of the qulonglong.