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. Dragging std::shared_ptr
Forum Updated to NodeBB v4.3 + New Features

Dragging std::shared_ptr

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 2.2k Views
  • 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.
  • C Offline
    C Offline
    cardio63
    wrote on 26 Jan 2016, 18:19 last edited by
    #1

    Greetings. I want to use drag-and-drop to drag a QTreeWidgetItem that has std::shared_ptr user data. Qt is throwing an exception because it doesn't know how to store the shared_ptr onto a QDataStream. I read a bit and it seems that Q_DECLARE_SMART_POINTER_METATYPE is supposed to allow this to work. However, I have not had any success. I have built a tiny example showing the problem. Does anyone know how to do this properly?

    In case you're wondering, I need to use shared_ptr (as opposed to other Qt shared pointers) because the pointer comes from a non-Qt part of the application (which I cannot control). I'm not comfortable converting the shared pointer to a raw pointer because it could go out of scope during my operation.

    Thank you.

    // DragSharedPtr.cpp
    
    #include <QtGlobal>
    #include <QMetaType>
    #include <QVariant>
    #include <QDataStream>
    
    #include <memory>
    
    Q_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr)
    Q_DECLARE_METATYPE(std::shared_ptr<int>);
    
    
    int main()
    {
        qRegisterMetaType< std::shared_ptr<int> >();
    
        // create variant holding the shared pointer (this works)
        auto spint = std::make_shared<int>(42);
        QVariant varspint = QVariant::fromValue(spint);
    
        // get the shared pointer back (this works)
        auto spint2 = varspint.value<std::shared_ptr<int>>();
        Q_ASSERT(spint2 == spint);
    
        // Try to encode the variant into a stream.  This is
        // needed when, for example, dragging the variant.
        //
        // This code compiles, but fails with a console warning:
        //
        //     QVariant::save: unable to save type  
        //                     'std:;shard_ptr<int>' (type id: 1024)
        //
        // and an exception:
        //    
        //     Program: <path to Qt>\bin\Qt5Cored.dll
        //     Module: 5.5.1
        //     File: <path to Qt>\src\corelib\global\qglobal.cpp
        //     Line: 2974
        //     ASSERT failure in QVariant::save: "Invalid type to save", 
        //            file <path...>\qvariant.cpp, line 2124
        //    
        QByteArray encoded;
        QDataStream stream(&encoded, QIODevice::WriteOnly);
        stream << varspint;
    
        return 0;
    }
    
    1 Reply Last reply
    0
    • J Offline
      J Offline
      jsulm
      Lifetime Qt Champion
      wrote on 27 Jan 2016, 05:52 last edited by
      #2

      You have to implement QDataStream & QDataStream::operator<<(std::shared_ptr<int>) and QDataStream & QDataStream::operator>>(std::shared_ptr<int>&). I don't see any other possibility, because QDataStream does not know how to serialize/deserialize a std::sgared_ptr.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • C Offline
        C Offline
        cardio63
        wrote on 27 Jan 2016, 19:19 last edited by
        #3

        Thanks. Yes, I ended up doing just that. I'm a bit concerned about lifetime of ownership, but I don't see a better way.

        1 Reply Last reply
        0

        1/3

        26 Jan 2016, 18:19

        • Login

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