Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. crash in QListWidget::dropEvent when I add a UserRole to my QListItemWidget :'(
Forum Updated to NodeBB v4.3 + New Features

crash in QListWidget::dropEvent when I add a UserRole to my QListItemWidget :'(

Scheduled Pinned Locked Moved Solved General and Desktop
27 Posts 4 Posters 4.0k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by
    #10

    The error comes from the fact that you have to register the metatype, not just declare it.

    The real issue here is that you are passing pointers around without a clear definition of who owns what. Be very careful not to leak memory or having double deletions

    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
    ~Napoleon Bonaparte

    On a crusade to banish setIndexWidget() from the holy land of Qt

    mbruelM 1 Reply Last reply
    0
    • VRoninV VRonin

      The error comes from the fact that you have to register the metatype, not just declare it.

      The real issue here is that you are passing pointers around without a clear definition of who owns what. Be very careful not to leak memory or having double deletions

      mbruelM Offline
      mbruelM Offline
      mbruel
      wrote on last edited by mbruel
      #11

      @VRonin
      Well it's kind of obscure to me how/when and mainly where we need to register the metatype.
      I've no issue anywhere else putting, reading Element* or QSet<Element*> in a QVariant, simply having declared those types.
      Why would it be different in this case for QListWidgetItem?
      I've added the registration in my constructor of my QListWidget but I still have the same error "QVariant::save: unable to save type 'Element*' (type id: 1052)."

      Here is what I've done:

      #include "Model/Element.h"
      ItemOfferingListWidget::ItemOfferingListWidget(QWidget *parent) :
          QListWidget(parent), _allowIternalMove(true)
      {
          setSelectionMode(QAbstractItemView::ExtendedSelection);
          setDragDropMode(QAbstractItemView::DragDrop);
          setDropIndicatorShown(true);
          qRegisterMetaType<Element *> ();
      //    setDragDropOverwriteMode(true);
      }
      

      For the use of raw pointers, I know it could be dangerous, but the architecture of the project is clear : I've a unique manager (Singleton) for each kind of object that is in charge of construction / deletion.

      VRoninV 1 Reply Last reply
      0
      • mbruelM mbruel

        @VRonin
        Well it's kind of obscure to me how/when and mainly where we need to register the metatype.
        I've no issue anywhere else putting, reading Element* or QSet<Element*> in a QVariant, simply having declared those types.
        Why would it be different in this case for QListWidgetItem?
        I've added the registration in my constructor of my QListWidget but I still have the same error "QVariant::save: unable to save type 'Element*' (type id: 1052)."

        Here is what I've done:

        #include "Model/Element.h"
        ItemOfferingListWidget::ItemOfferingListWidget(QWidget *parent) :
            QListWidget(parent), _allowIternalMove(true)
        {
            setSelectionMode(QAbstractItemView::ExtendedSelection);
            setDragDropMode(QAbstractItemView::DragDrop);
            setDropIndicatorShown(true);
            qRegisterMetaType<Element *> ();
        //    setDragDropOverwriteMode(true);
        }
        

        For the use of raw pointers, I know it could be dangerous, but the architecture of the project is clear : I've a unique manager (Singleton) for each kind of object that is in charge of construction / deletion.

        VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by VRonin
        #12

        @mbruel said in crash in QListWidget::dropEvent when I add a UserRole to my QListItemWidget :'(:

        how/when and mainly where we need to register the metatype

        Normally you call that method inside the main() so you can forget about it for the rest of your program.

        Why would it be different in this case for QListWidgetItem?

        It isn't

        I've a unique manager (Singleton)

        http://lengthily.blogspot.com/2017/02/one-size-fits-all.html

        Also keep in mind that Qt-parent child relationship does not know about your design so it might delete stuff you didn't intend to

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        mbruelM 1 Reply Last reply
        0
        • M Offline
          M Offline
          mpergand
          wrote on last edited by mpergand
          #13

          There was a topic recently about this issue here:
          https://forum.qt.io/topic/85798/save-qset-using-qsettings/17

          Seems you need to implement the stream operators << >>

          This code works without error:

          class FooClass {};
          Q_DECLARE_METATYPE(FooClass*)
          
          QDataStream &operator<<(QDataStream &out, const FooClass*& foo) {
          
              out<< foo;
          
              return out;
          }
          
          QDataStream &operator>>(QDataStream &in, FooClass*& foo) {
          
              in>>foo;
              return in;
          }
          
          
          int main(int argc, char *argv[])
          {
          qRegisterMetaType<FooClass *> ("fooclasspt");
          FooClass foo;
          QVariant v=QVariant::fromValue(&foo);
          FooClass* fooPt=v.value<FooClass*>();
          qDebug()<<&foo<<fooPt; // same address
          
          qRegisterMetaTypeStreamOperators<FooClass *> ();
          
          QByteArray encoded;
          QDataStream stream(&encoded, QIODevice::WriteOnly);
          stream<<v;
          
          return 0;
          }
          
          mrjjM mbruelM 2 Replies Last reply
          1
          • M mpergand

            There was a topic recently about this issue here:
            https://forum.qt.io/topic/85798/save-qset-using-qsettings/17

            Seems you need to implement the stream operators << >>

            This code works without error:

            class FooClass {};
            Q_DECLARE_METATYPE(FooClass*)
            
            QDataStream &operator<<(QDataStream &out, const FooClass*& foo) {
            
                out<< foo;
            
                return out;
            }
            
            QDataStream &operator>>(QDataStream &in, FooClass*& foo) {
            
                in>>foo;
                return in;
            }
            
            
            int main(int argc, char *argv[])
            {
            qRegisterMetaType<FooClass *> ("fooclasspt");
            FooClass foo;
            QVariant v=QVariant::fromValue(&foo);
            FooClass* fooPt=v.value<FooClass*>();
            qDebug()<<&foo<<fooPt; // same address
            
            qRegisterMetaTypeStreamOperators<FooClass *> ();
            
            QByteArray encoded;
            QDataStream stream(&encoded, QIODevice::WriteOnly);
            stream<<v;
            
            return 0;
            }
            
            mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #14

            @mpergand
            hmm, trying code. it does not seem to call
            the operators ?

            1 Reply Last reply
            0
            • M Offline
              M Offline
              mpergand
              wrote on last edited by
              #15

              You're right, but :

              If the stream operators are not implemented you've got the QVariant::save: unable to save type error

              more over, if you change :
              QDataStream &operator<<(QDataStream &out, const FooClass*& foo)
              to
              QDataStream &operator<<(QDataStream &out, const FooClass* foo)

              without a reference to a pointer, it crashes here.

              mrjjM 1 Reply Last reply
              0
              • M mpergand

                You're right, but :

                If the stream operators are not implemented you've got the QVariant::save: unable to save type error

                more over, if you change :
                QDataStream &operator<<(QDataStream &out, const FooClass*& foo)
                to
                QDataStream &operator<<(QDataStream &out, const FooClass* foo)

                without a reference to a pointer, it crashes here.

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by mrjj
                #16

                @mpergand
                yeah, its pretty odd why one cant step into the function then.
                ( since it wants it )

                I assume at run time, it maps to others overloads then.
                update:
                in any case, steaming it out/in and using it seems to work :)

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mpergand
                  wrote on last edited by
                  #17

                  I'm unable to retreive the variant.

                  QDataStream out(&encoded, QIODevice::ReadOnly);
                  QVariant v2;
                  out>>v2;
                  
                  QDataStream &operator>>(QDataStream &in, FooClass*& foo) {
                      in>>foo; -> It crashes here
                  
                  1 Reply Last reply
                  0
                  • VRoninV VRonin

                    @mbruel said in crash in QListWidget::dropEvent when I add a UserRole to my QListItemWidget :'(:

                    how/when and mainly where we need to register the metatype

                    Normally you call that method inside the main() so you can forget about it for the rest of your program.

                    Why would it be different in this case for QListWidgetItem?

                    It isn't

                    I've a unique manager (Singleton)

                    http://lengthily.blogspot.com/2017/02/one-size-fits-all.html

                    Also keep in mind that Qt-parent child relationship does not know about your design so it might delete stuff you didn't intend to

                    mbruelM Offline
                    mbruelM Offline
                    mbruel
                    wrote on last edited by
                    #18

                    @VRonin said in crash in QListWidget::dropEvent when I add a UserRole to my QListItemWidget :'(:

                    http://lengthily.blogspot.com/2017/02/one-size-fits-all.html
                    Also keep in mind that Qt-parent child relationship does not know about your design so it might delete stuff you didn't intend to

                    Well, I said manager to not enter in the details... but basically it's a subclass of QApplication that owns my Model (which own all the Elements). It also owns the HMI if there is one.

                    class MyApplication : public QApplication
                    {
                    private:
                        const AppMode _mode;
                        AppLang       _lang;
                    
                        Model        *_model;
                        MainWindow   *_hmi;
                    
                        static const QMap<AppLang, QString> sAppLanguages;
                        static const QString sTranslationsFileName;
                    
                        static const QString sVersion;
                        static const QString sAppName;
                    ...
                    };
                    

                    However I use singleton for some thread safe objects as a convenient way to be able to get the instance from anywhere in the code. Mainly for to get my LogService, the IconFactory, the UndoStack and the IOService.
                    I think it has some sense and it is practical to be able to do such calls:

                    Iconfactory::getInstance()->getElementTypeIcon(elem->getElementType);
                    UndoStack::getInstance()->beginMacro(macroLabel);
                    

                    Here is what the Singleton class I use:

                    #ifndef SINGLETON_H
                    #define SINGLETON_H
                    
                    template <typename T> class Singleton
                    {
                    protected:
                        // Constructor /Destructor
                        Singleton() = default;
                        virtual ~Singleton() = default;
                    
                    public:
                        Singleton(const Singleton &other) = delete;
                        Singleton(const Singleton &&other) = delete;
                        Singleton & operator=(const Singleton &other) = delete;
                        Singleton & operator=(const Singleton &&other) = delete;
                    
                        // Public Interface
                        static T *getInstance(){
                            if (!_singleton) {
                                _singleton = new T;
                            }
                            return (static_cast<T*> (_singleton));
                        }
                    
                        static void kill()
                        {
                            if (_singleton)
                            {
                                delete _singleton;
                                _singleton = nullptr;
                            }
                        }
                    
                    private:
                        // Unique instance
                        static T *_singleton;
                    };
                    
                    template <typename T> T *Singleton<T>::_singleton;
                    #endif // SINGLETON_H
                    

                    Rq: for Services, I generally derive from this PureStaticClass

                    class PureStaticClass
                    {
                        PureStaticClass() = delete;
                        PureStaticClass(const PureStaticClass &other) = delete;
                        PureStaticClass(const PureStaticClass &&other) = delete;
                    
                        PureStaticClass & operator=(const PureStaticClass &other) = delete;
                        PureStaticClass & operator=(const PureStaticClass &&other) = delete;
                    };
                    

                    @VRonin said in crash in QListWidget::dropEvent when I add a UserRole to my QListItemWidget :'(:

                    Also keep in mind that Qt-parent child relationship does not know about your design so it might delete stuff you didn't intend to

                    Yes I'm aware of that, I do it only for my Data Object that aren't updated directly by any QT objects. Those objects will have a pointer on them to extract some data but never delete it.

                    1 Reply Last reply
                    0
                    • M mpergand

                      There was a topic recently about this issue here:
                      https://forum.qt.io/topic/85798/save-qset-using-qsettings/17

                      Seems you need to implement the stream operators << >>

                      This code works without error:

                      class FooClass {};
                      Q_DECLARE_METATYPE(FooClass*)
                      
                      QDataStream &operator<<(QDataStream &out, const FooClass*& foo) {
                      
                          out<< foo;
                      
                          return out;
                      }
                      
                      QDataStream &operator>>(QDataStream &in, FooClass*& foo) {
                      
                          in>>foo;
                          return in;
                      }
                      
                      
                      int main(int argc, char *argv[])
                      {
                      qRegisterMetaType<FooClass *> ("fooclasspt");
                      FooClass foo;
                      QVariant v=QVariant::fromValue(&foo);
                      FooClass* fooPt=v.value<FooClass*>();
                      qDebug()<<&foo<<fooPt; // same address
                      
                      qRegisterMetaTypeStreamOperators<FooClass *> ();
                      
                      QByteArray encoded;
                      QDataStream stream(&encoded, QIODevice::WriteOnly);
                      stream<<v;
                      
                      return 0;
                      }
                      
                      mbruelM Offline
                      mbruelM Offline
                      mbruel
                      wrote on last edited by
                      #19

                      @mpergand
                      I've tried that and it doesn't work with work on my env. I'm still getting the issue:

                      QVariant::save: unable to save type 'Element*' (type id: 1025).
                      

                      Here is my code:

                      #include <QDataStream>
                      class Element;
                      inline QDataStream &operator>>(QDataStream &in, Element*& elem) {
                      
                          in >> elem;
                          return in;
                      }
                      inline QDataStream &operator<<(QDataStream &in, Element*& elem) {
                      
                          in << elem;
                          return in;
                      }
                      

                      if I override the startDrag event like this:

                      void ItemOfferingListWidget::startDrag(Qt::DropActions supportedActions)
                      {
                      //   return QListWidget::startDrag(supportedActions);
                          Q_UNUSED(supportedActions)
                          QMimeData       *mimeData = new QMimeData();
                          QByteArray       encodedData;
                          QDataStream stream(&encodedData, QIODevice::WriteOnly);
                          for (QListWidgetItem *item  : selectedItems())
                          {
                              QMap<int, QVariant> data;
                              data[Qt::UserRole] =  item->data(Qt::UserRole);
                      //        Element *elem = item->data(Qt::UserRole).value<Element*>();
                      //        qulonglong ptrval(*reinterpret_cast<qulonglong *>(&elem));
                              stream << row(item) << data;
                      //        stream << row(item) << elem->getId() << elem->getElementTypeName();
                          }
                          mimeData->setData("application/x-qabstractitemmodeldatalist", encodedData);
                          QDrag *drag = new QDrag(this);
                          drag->setMimeData(mimeData);
                          drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
                      }
                      

                      The error message kicks in when I try to write the data in the stream.
                      I'm jumping in

                      template <class Key, class T>
                      inline QDataStream &operator<<(QDataStream &s, const QMap<Key, T> &map)
                      {
                          return QtPrivate::writeAssociativeContainer(s, map);
                      }
                      

                      but never in my overriden function :(

                      1 Reply Last reply
                      0
                      • VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by VRonin
                        #20

                        My fault, I totally forgot you also need qRegisterMetaTypeStreamOperators

                        P.S.
                        I still don't like your design but at the end of the day if you are happy with it and it works, go for it

                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                        ~Napoleon Bonaparte

                        On a crusade to banish setIndexWidget() from the holy land of Qt

                        mbruelM 1 Reply Last reply
                        2
                        • VRoninV VRonin

                          My fault, I totally forgot you also need qRegisterMetaTypeStreamOperators

                          P.S.
                          I still don't like your design but at the end of the day if you are happy with it and it works, go for it

                          mbruelM Offline
                          mbruelM Offline
                          mbruel
                          wrote on last edited by mbruel
                          #21

                          @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.
                          
                          VRoninV 1 Reply Last reply
                          0
                          • mbruelM mbruel

                            @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.
                            
                            VRoninV Offline
                            VRoninV Offline
                            VRonin
                            wrote on last edited by
                            #22

                            That's because your code is an obvious infinite recursion. You have to fix it

                            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                            ~Napoleon Bonaparte

                            On a crusade to banish setIndexWidget() from the holy land of Qt

                            1 Reply Last reply
                            0
                            • M Offline
                              M Offline
                              mpergand
                              wrote on last edited by mpergand
                              #23

                              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à

                              mbruelM 1 Reply Last reply
                              0
                              • mbruelM Offline
                                mbruelM Offline
                                mbruel
                                wrote on last edited by
                                #24

                                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)

                                1 Reply Last reply
                                0
                                • M mpergand

                                  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à

                                  mbruelM Offline
                                  mbruelM Offline
                                  mbruel
                                  wrote on last edited by
                                  #25

                                  @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*

                                  @VRonin

                                  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

                                  VRoninV 1 Reply Last reply
                                  0
                                  • mbruelM mbruel

                                    @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*

                                    @VRonin

                                    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

                                    VRoninV Offline
                                    VRoninV Offline
                                    VRonin
                                    wrote on last edited by VRonin
                                    #26

                                    @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; calls QDataStream &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

                                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                    ~Napoleon Bonaparte

                                    On a crusade to banish setIndexWidget() from the holy land of Qt

                                    mbruelM 1 Reply Last reply
                                    2
                                    • VRoninV VRonin

                                      @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; calls QDataStream &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

                                      mbruelM Offline
                                      mbruelM Offline
                                      mbruel
                                      wrote on last edited by
                                      #27

                                      @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.

                                      1 Reply Last reply
                                      0

                                      • Login

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • Users
                                      • Groups
                                      • Search
                                      • Get Qt Extensions
                                      • Unsolved