qtqt-signalsboost-smart-ptr

Qt Signals and Slots with Boost::smart_ptr


So what I am trying to do is use Qt signals and slots to pass around an image through a smart_ptr so that it will delete itself when everything that needs to use the data is done accessing it.

Here is the code I have:

Class A, inherits QObject:

signals:
void newImageSent(boost::shared_ptr<namespace::ImageData> &image);

Class B, inherits QObject:

public slots:
void newImageRecieved(boost::shared_ptr<namespace::ImageData> &image)
{ 
// Manipulate Image 
}

Connection Code:

QObject::connect(classAPtr.get(),
SIGNAL(newImageSent(boost::shared_ptr<namespace::ImageData>)),
classBPtr.get(),
SLOT(newImageRecieved(boost::shared_ptr<namespace::ImageData>)),
Qt::QueuedConnection);

When I try to do the connection is always returns false though, so is there something I am missing?


Solution

  • In a queued connection the signal is queued in the event loop and its parameters are copied. Therefore the slot is not directly executed. To make copying possible you have to register the type via qRegisterMetaType, see also here.

    Since you are using shared pointers easiest solution would be to transmit them by value, then you would not have to bother with the references as Frank Osterfeld pointed out.

    The way you create the connection is string based and as result is easy to get wrong, especially when namespaces are involved. Using typedef would ease the pain a little and make it easier to spot errors. For example you could do

    typedef boost::shared_ptr<namespace::ImageData> ImageDataPtr;
    

    and use ImageDataPtr from then on. Especially on registering the type as meta type which you have to do since you are using a queued connection.

    If you are using Qt5 then you can rely on the new connection syntax which ensures correctness during compilation as it does not rely on string comparisons:

    QObject::connect(classAPtr.get(), &A::newImageSent,
                     classBPtr.get(), &B::newImageRecieved,
                     Qt::QueuedConnection);