Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QSharedPointer<UserDataType> as signal/slot parameters



  • In general a user data type should be registered with the meta system in order to be used as parameters in signal/slot queued communication. How about a QSharedPointer to a user data type. Is that safe? Does it matter if the user data type is registered?

    If QSharedPointer can't be used I suppose a raw pointer would be ok (provided I can manage the lifetime of the object correctly). Right?

    Thanks



  • You should be able to use it as a parameter ok, I think, especially if your signal-slot connections are direct and not queued.



  • The connection in question is queued.



  • In that case, I think you need to register them. Make a typedef for QSharedPointer<UserDataType>, and use both Q_DECLARE_METATYPE as well as qRegisterMetaType() to register it for use.



  • [quote author="Andre" date="1306394817"]In that case, I think you need to register them. Make a typedef for QSharedPointer<UserDataType>, and use both Q_DECLARE_METATYPE as well as qRegisterMetaType() to register it for use. [/quote]
    Correct. The Q_DECLARE_METATYPE macro is necessary in both cases. qRegisterMetaType is required for the queued connection.



  • I have similiar problem and can't get QSharedPointer<QVector<quint16> > working with signals&slots. A little example would be very helpful. Thank you in advance.



  • Off the top of my head:

    @
    typedef QSharedPointer<QVector<quint16> > SharedIntVectorPointer;
    Q_DECLARE_METATYPE(SharedIntVectorPointer)
    qRegisterMetaType<SharedIntVectorPointer>();
    @

    But do read up on the documentation of "QMetaType":http://qt-project.org/doc/qt-5/qmetatype.html.



  • Not quite. The typedef and the Q_DECLARE_METATYPE are declarations that belong in a header file, the qRegisterMetaType is something that needs to be called from an implementation somewhere. If you put them together like you show, it won't work (and likely won't compile even).

    I either create a section somewhere in my application initialization to call these qRegisterMetaType's, or I use an initialization like this in a .cpp file that is closely related to the type I am trying to register:

    @
    //in an implementation file outside of any function!
    const int MyType::typeId = qRegisterMetaType<MyType>("MyType");
    @

    Note that in this case, I keep the typeId in a static variable in the type itself, but any static variable will do.



  • [quote author="Andre" date="1412256899"]Not quite. The typedef and the Q_DECLARE_METATYPE are declarations that belong in a header file, the qRegisterMetaType is something that needs to be called from an implementation somewhere. [/quote]

    That kind of depends on how widely they are used.

    [quote]If you put them together like you show, it won't work (and likely won't compile even).[/quote]

    Possibly due to the fact that I didn't add the const int instantiation. Other than that, it would work fine in a self-contained cpp file. But again, I didn't test this today, so I might be horribly off.

    Edit: fixed horrible quoting



  • Thank you both, got it working finally. I've put typedef and Q_DECLARE_METATYPE in a header file and qRegisterMetaType just before connecting signals&slots. Not sure about the latter one though, is it correct aproach?



  • It works, but generally it's better to take the approach Andre suggests. This will prevent unpleasant surprises if your application grows and starts using the signals and slots before you call qRegisterMetaType().



  • BTW, why do you have a QVector in a QSharedPointer? It's already "implicitly shared":http://doc.qt.io/qt-5/implicit-sharing.html, so you can just make it a stack/auto variable (not use 'new') and it should work fine and fast.



  • BTW, why do you have a QVector in a QSharedPointer? It's already "implicitly shared":http://doc.qt.io/qt-5/implicit-sharing.html, so you can just make it a stack/auto variable (not use 'new') and it should work fine and fast.



  • Hi all,

    Based on your comments and suggestion I build a simple application using QSharedPointer.

    So far, the application is running as expected however, when the same is debugging using GDB, a segmentation fault show up.

    I just created a new post (as suggested by system) about this.

    https://forum.qt.io/topic/65422/qsharedpointer-qregistermetatype-gdb-and-slots

    Appreciated your feedback.

    Julio



  • @halfgaar Implicit sharing has copy on write so it is not the same as passing pointers around.


  • Qt Champions 2017

    @Jakob-Schou
    It is, if you pass immutable objects, and besides that post is quite old ...


Log in to reply